Differences Between: [Versions 310 and 403] [Versions 311 and 403] [Versions 39 and 403] [Versions 400 and 403] [Versions 401 and 403] [Versions 402 and 403]
1 <?php 2 // This file is part of Moodle - http://moodle.org/ 3 // 4 // Moodle is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // Moodle is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 16 17 /** 18 * Class to manage the custom filetypes list that is stored in a config variable. 19 * 20 * @package core 21 * @copyright 2014 The Open University 22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 */ 24 25 defined('MOODLE_INTERNAL') || die(); 26 27 require_once($CFG->libdir . '/filelib.php'); 28 29 /** 30 * Class to manage the custom filetypes list that is stored in a config variable. 31 * 32 * @copyright 2014 The Open University 33 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 34 */ 35 abstract class core_filetypes { 36 /** @var array Cached MIME types for current request */ 37 protected static $cachedtypes; 38 39 /** 40 * Gets default MIME types that are included as standard. 41 * 42 * Note: Use the function get_mimetypes_array to access this data including 43 * any customisations the user might have made. 44 * 45 * @return array Default (pre-installed) MIME type information 46 */ 47 protected static function get_default_types() { 48 return array( 49 'xxx' => array('type' => 'document/unknown', 'icon' => 'unknown'), 50 '3gp' => array('type' => 'video/quicktime', 'icon' => 'video', 'groups' => array('video'), 'string' => 'video'), 51 '7z' => array('type' => 'application/x-7z-compressed', 'icon' => 'archive', 52 'groups' => array('archive'), 'string' => 'archive'), 53 'aac' => array('type' => 'audio/aac', 'icon' => 'audio', 'groups' => array('audio', 'html_audio', 'web_audio'), 54 'string' => 'audio'), 55 'accdb' => array('type' => 'application/msaccess', 'icon' => 'database'), 56 'ai' => array('type' => 'application/postscript', 'icon' => 'eps', 'groups' => array('image'), 'string' => 'image'), 57 'aif' => array('type' => 'audio/x-aiff', 'icon' => 'audio', 'groups' => array('audio'), 'string' => 'audio'), 58 'aiff' => array('type' => 'audio/x-aiff', 'icon' => 'audio', 'groups' => array('audio'), 'string' => 'audio'), 59 'aifc' => array('type' => 'audio/x-aiff', 'icon' => 'audio', 'groups' => array('audio'), 'string' => 'audio'), 60 'applescript' => array('type' => 'text/plain', 'icon' => 'text'), 61 'asc' => array('type' => 'text/plain', 'icon' => 'sourcecode'), 62 'asm' => array('type' => 'text/plain', 'icon' => 'sourcecode'), 63 'au' => array('type' => 'audio/au', 'icon' => 'audio', 'groups' => array('audio'), 'string' => 'audio'), 64 'avi' => array('type' => 'video/x-ms-wm', 'icon' => 'video', 65 'groups' => array('video', 'web_video'), 'string' => 'video'), 66 'bmp' => array('type' => 'image/bmp', 'icon' => 'image', 'groups' => array('image'), 'string' => 'image'), 67 'c' => array('type' => 'text/plain', 'icon' => 'sourcecode'), 68 'cct' => array('type' => 'shockwave/director', 'icon' => 'flash'), 69 'cpp' => array('type' => 'text/plain', 'icon' => 'sourcecode'), 70 'cs' => array('type' => 'application/x-csh', 'icon' => 'sourcecode'), 71 'css' => array('type' => 'text/css', 'icon' => 'json', 'groups' => array('web_file')), 72 'csv' => array('type' => 'text/csv', 'icon' => 'spreadsheet', 'groups' => array('spreadsheet')), 73 'dv' => array('type' => 'video/x-dv', 'icon' => 'video', 'groups' => array('video'), 'string' => 'video'), 74 'dmg' => array('type' => 'application/octet-stream', 'icon' => 'unknown'), 75 76 'doc' => array('type' => 'application/msword', 'icon' => 'document', 'groups' => array('document')), 77 'bdoc' => array('type' => 'application/x-digidoc', 'icon' => 'document', 'groups' => array('archive')), 78 'cdoc' => array('type' => 'application/x-digidoc', 'icon' => 'document', 'groups' => array('archive')), 79 'ddoc' => array('type' => 'application/x-digidoc', 'icon' => 'document', 'groups' => array('archive')), 80 'docx' => array('type' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', 81 'icon' => 'document', 'groups' => array('document')), 82 'docm' => array('type' => 'application/vnd.ms-word.document.macroEnabled.12', 'icon' => 'document'), 83 'dotx' => array('type' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.template', 84 'icon' => 'document'), 85 'dotm' => array('type' => 'application/vnd.ms-word.template.macroEnabled.12', 'icon' => 'document'), 86 87 'dcr' => array('type' => 'application/x-director', 'icon' => 'flash'), 88 'dif' => array('type' => 'video/x-dv', 'icon' => 'video', 'groups' => array('video'), 'string' => 'video'), 89 'dir' => array('type' => 'application/x-director', 'icon' => 'flash'), 90 'dxr' => array('type' => 'application/x-director', 'icon' => 'flash'), 91 'eps' => array('type' => 'application/postscript', 'icon' => 'eps'), 92 'epub' => array('type' => 'application/epub+zip', 'icon' => 'epub', 'groups' => array('document')), 93 'fdf' => array('type' => 'application/vnd.fdf', 'icon' => 'pdf'), 94 'flac' => array('type' => 'audio/flac', 'icon' => 'audio', 'groups' => array('audio', 'html_audio', 'web_audio'), 95 'string' => 'audio'), 96 'flv' => array('type' => 'video/x-flv', 'icon' => 'flash', 97 'groups' => array('video', 'web_video'), 'string' => 'video'), 98 'f4v' => array('type' => 'video/mp4', 'icon' => 'flash', 'groups' => array('video', 'web_video'), 'string' => 'video'), 99 'fmp4' => array('type' => 'video/mp4', 'icon' => 'video', 'groups' => array('html_video', 'video', 'web_video'), 100 'string' => 'video'), 101 'gallery' => array('type' => 'application/x-smarttech-notebook', 'icon' => 'archive'), 102 'galleryitem' => array('type' => 'application/x-smarttech-notebook', 'icon' => 'archive'), 103 'gallerycollection' => array('type' => 'application/x-smarttech-notebook', 'icon' => 'archive'), 104 'gdraw' => array('type' => 'application/vnd.google-apps.drawing', 'icon' => 'image', 'groups' => array('image')), 105 'gdoc' => array('type' => 'application/vnd.google-apps.document', 'icon' => 'document', 'groups' => array('document')), 106 'gsheet' => array('type' => 'application/vnd.google-apps.spreadsheet', 'icon' => 'spreadsheet', 107 'groups' => array('spreadsheet')), 108 'gslides' => array('type' => 'application/vnd.google-apps.presentation', 'icon' => 'powerpoint', 109 'groups' => array('presentation')), 110 'gif' => array('type' => 'image/gif', 'icon' => 'gif', 'groups' => array('image', 'web_image', 'optimised_image'), 111 'string' => 'image'), 112 'gtar' => array('type' => 'application/x-gtar', 'icon' => 'archive', 113 'groups' => array('archive'), 'string' => 'archive'), 114 'tgz' => array('type' => 'application/g-zip', 'icon' => 'archive', 'groups' => array('archive'), 'string' => 'archive'), 115 'gz' => array('type' => 'application/g-zip', 'icon' => 'archive', 'groups' => array('archive'), 'string' => 'archive'), 116 'gzip' => array('type' => 'application/g-zip', 'icon' => 'archive', 117 'groups' => array('archive'), 'string' => 'archive'), 118 'h' => array('type' => 'text/plain', 'icon' => 'sourcecode'), 119 'h5p' => array('type' => 'application/zip.h5p', 'icon' => 'h5p', 'string' => 'archive'), 120 'hpp' => array('type' => 'text/plain', 'icon' => 'sourcecode'), 121 'hqx' => array('type' => 'application/mac-binhex40', 'icon' => 'archive', 122 'groups' => array('archive'), 'string' => 'archive'), 123 'htc' => array('type' => 'text/x-component', 'icon' => 'markup'), 124 'html' => array('type' => 'text/html', 'icon' => 'markup', 'groups' => array('web_file')), 125 'xhtml' => array('type' => 'application/xhtml+xml', 'icon' => 'markup', 'groups' => array('web_file')), 126 'htm' => array('type' => 'text/html', 'icon' => 'markup', 'groups' => array('web_file')), 127 'ico' => array('type' => 'image/vnd.microsoft.icon', 'icon' => 'image', 128 'groups' => array('image'), 'string' => 'image'), 129 'ics' => array('type' => 'text/calendar', 'icon' => 'text'), 130 'isf' => array('type' => 'application/inspiration', 'icon' => 'isf'), 131 'ist' => array('type' => 'application/inspiration.template', 'icon' => 'isf'), 132 'java' => array('type' => 'text/plain', 'icon' => 'sourcecode'), 133 'jar' => array('type' => 'application/java-archive', 'icon' => 'archive'), 134 'jcb' => array('type' => 'text/xml', 'icon' => 'markup'), 135 'jcl' => array('type' => 'text/xml', 'icon' => 'markup'), 136 'jcw' => array('type' => 'text/xml', 'icon' => 'markup'), 137 'jmt' => array('type' => 'text/xml', 'icon' => 'markup'), 138 'jmx' => array('type' => 'text/xml', 'icon' => 'markup'), 139 'jnlp' => array('type' => 'application/x-java-jnlp-file', 'icon' => 'markup'), 140 'jpe' => array('type' => 'image/jpeg', 'icon' => 'image', 'groups' => array('image', 'web_image', 'optimised_image'), 141 'string' => 'image'), 142 'jpeg' => array('type' => 'image/jpeg', 'icon' => 'image', 'groups' => array('image', 'web_image', 'optimised_image'), 143 'string' => 'image'), 144 'jpg' => array('type' => 'image/jpeg', 'icon' => 'image', 'groups' => array('image', 'web_image', 'optimised_image'), 145 'string' => 'image'), 146 'jqz' => array('type' => 'text/xml', 'icon' => 'markup'), 147 'js' => array('type' => 'application/x-javascript', 'icon' => 'text', 'groups' => array('web_file')), 148 'json' => array('type' => 'application/json', 'icon' => 'json'), 149 'latex' => array('type' => 'application/x-latex', 'icon' => 'text'), 150 'm' => array('type' => 'text/plain', 'icon' => 'sourcecode'), 151 'mbz' => array('type' => 'application/vnd.moodle.backup', 'icon' => 'moodle'), 152 'mdb' => array('type' => 'application/x-msaccess', 'icon' => 'database'), 153 'mht' => array('type' => 'message/rfc822', 'icon' => 'archive'), 154 'mhtml' => array('type' => 'message/rfc822', 'icon' => 'archive'), 155 'mov' => array('type' => 'video/quicktime', 'icon' => 'video', 156 'groups' => array('video', 'web_video', 'html_video'), 'string' => 'video'), 157 'movie' => array('type' => 'video/x-sgi-movie', 'icon' => 'video', 'groups' => array('video'), 'string' => 'video'), 158 'mw' => array('type' => 'application/maple', 'icon' => 'math'), 159 'mws' => array('type' => 'application/maple', 'icon' => 'math'), 160 'm3u' => array('type' => 'audio/x-mpegurl', 'icon' => 'audio', 'groups' => array('audio'), 'string' => 'audio'), 161 'm3u8' => array('type' => 'application/x-mpegURL', 'icon' => 'video', 'groups' => array('media_source')), 162 'mp3' => array('type' => 'audio/mp3', 'icon' => 'audio', 'groups' => array('audio', 'html_audio', 'web_audio'), 163 'string' => 'audio'), 164 'mp4' => array('type' => 'video/mp4', 'icon' => 'video', 'groups' => array('html_video', 'video', 'web_video'), 165 'string' => 'video'), 166 'm4v' => array('type' => 'video/mp4', 'icon' => 'video', 'groups' => array('html_video', 'video', 'web_video'), 167 'string' => 'video'), 168 'm4a' => array('type' => 'audio/mp4', 'icon' => 'audio', 'groups' => array('audio', 'html_audio', 'web_audio'), 169 'string' => 'audio'), 170 'mpeg' => array('type' => 'video/mpeg', 'icon' => 'video', 'groups' => array('video', 'web_video'), 171 'string' => 'video'), 172 'mpd' => array('type' => 'application/dash+xml', 'icon' => 'video', 'groups' => array('media_source')), 173 'mpe' => array('type' => 'video/mpeg', 'icon' => 'video', 'groups' => array('video', 'web_video'), 174 'string' => 'video'), 175 'mpg' => array('type' => 'video/mpeg', 'icon' => 'video', 'groups' => array('video', 'web_video'), 176 'string' => 'video'), 177 'mpr' => array('type' => 'application/vnd.moodle.profiling', 'icon' => 'moodle'), 178 179 'nbk' => array('type' => 'application/x-smarttech-notebook', 'icon' => 'archive'), 180 'notebook' => array('type' => 'application/x-smarttech-notebook', 'icon' => 'archive'), 181 182 'odt' => array('type' => 'application/vnd.oasis.opendocument.text', 'icon' => 'writer', 'groups' => array('document')), 183 'ott' => array('type' => 'application/vnd.oasis.opendocument.text-template', 184 'icon' => 'writer', 'groups' => array('document')), 185 'oth' => array('type' => 'application/vnd.oasis.opendocument.text-web', 'icon' => 'oth', 'groups' => array('document')), 186 'odm' => array('type' => 'application/vnd.oasis.opendocument.text-master', 'icon' => 'writer'), 187 'odg' => array('type' => 'application/vnd.oasis.opendocument.graphics', 'icon' => 'draw'), 188 'otg' => array('type' => 'application/vnd.oasis.opendocument.graphics-template', 'icon' => 'draw'), 189 'odp' => array('type' => 'application/vnd.oasis.opendocument.presentation', 'icon' => 'impress', 190 'groups' => array('presentation')), 191 'otp' => array('type' => 'application/vnd.oasis.opendocument.presentation-template', 'icon' => 'impress', 192 'groups' => array('presentation')), 193 'ods' => array('type' => 'application/vnd.oasis.opendocument.spreadsheet', 194 'icon' => 'calc', 'groups' => array('spreadsheet')), 195 'ots' => array('type' => 'application/vnd.oasis.opendocument.spreadsheet-template', 196 'icon' => 'calc', 'groups' => array('spreadsheet')), 197 'odc' => array('type' => 'application/vnd.oasis.opendocument.chart', 'icon' => 'chart'), 198 'odf' => array('type' => 'application/vnd.oasis.opendocument.formula', 'icon' => 'math'), 199 'odb' => array('type' => 'application/vnd.oasis.opendocument.database', 'icon' => 'database'), 200 'odi' => array('type' => 'application/vnd.oasis.opendocument.image', 'icon' => 'draw'), 201 'oga' => array('type' => 'audio/ogg', 'icon' => 'audio', 'groups' => array('audio', 'html_audio', 'web_audio'), 202 'string' => 'audio'), 203 'ogg' => array('type' => 'audio/ogg', 'icon' => 'audio', 'groups' => array('audio', 'html_audio', 'web_audio'), 204 'string' => 'audio'), 205 'ogv' => array('type' => 'video/ogg', 'icon' => 'video', 'groups' => array('html_video', 'video', 'web_video'), 206 'string' => 'video'), 207 208 'pct' => array('type' => 'image/pict', 'icon' => 'image', 'groups' => array('image'), 'string' => 'image'), 209 'pdf' => array('type' => 'application/pdf', 'icon' => 'pdf', 'groups' => array('document')), 210 'php' => array('type' => 'text/plain', 'icon' => 'sourcecode'), 211 'pic' => array('type' => 'image/pict', 'icon' => 'image', 'groups' => array('image'), 'string' => 'image'), 212 'pict' => array('type' => 'image/pict', 'icon' => 'image', 'groups' => array('image'), 'string' => 'image'), 213 'png' => array('type' => 'image/png', 'icon' => 'image', 'groups' => array('image', 'web_image', 'optimised_image'), 214 'string' => 'image'), 215 'pps' => array('type' => 'application/vnd.ms-powerpoint', 'icon' => 'powerpoint', 'groups' => array('presentation')), 216 'ppt' => array('type' => 'application/vnd.ms-powerpoint', 'icon' => 'powerpoint', 'groups' => array('presentation')), 217 'pptx' => array('type' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation', 218 'icon' => 'powerpoint', 'groups' => array('presentation')), 219 'pptm' => array('type' => 'application/vnd.ms-powerpoint.presentation.macroEnabled.12', 'icon' => 'powerpoint', 220 'groups' => array('presentation')), 221 'potx' => array('type' => 'application/vnd.openxmlformats-officedocument.presentationml.template', 222 'icon' => 'powerpoint', 'groups' => array('presentation')), 223 'potm' => array('type' => 'application/vnd.ms-powerpoint.template.macroEnabled.12', 'icon' => 'powerpoint', 224 'groups' => array('presentation')), 225 'ppam' => array('type' => 'application/vnd.ms-powerpoint.addin.macroEnabled.12', 'icon' => 'powerpoint', 226 'groups' => array('presentation')), 227 'ppsx' => array('type' => 'application/vnd.openxmlformats-officedocument.presentationml.slideshow', 228 'icon' => 'powerpoint', 'groups' => array('presentation')), 229 'ppsm' => array('type' => 'application/vnd.ms-powerpoint.slideshow.macroEnabled.12', 'icon' => 'powerpoint', 230 'groups' => array('presentation')), 231 'ps' => array('type' => 'application/postscript', 'icon' => 'pdf'), 232 'psd' => array('type' => 'image/vnd.adobe.photoshop', 'icon' => 'psd'), 233 'pub' => array('type' => 'application/x-mspublisher', 'icon' => 'publisher', 'groups' => array('presentation')), 234 235 'qt' => array('type' => 'video/quicktime', 'icon' => 'video', 236 'groups' => array('video', 'web_video'), 'string' => 'video'), 237 'ra' => array('type' => 'audio/x-realaudio-plugin', 'icon' => 'audio', 238 'groups' => array('audio', 'web_audio'), 'string' => 'audio'), 239 'ram' => array('type' => 'audio/x-pn-realaudio-plugin', 'icon' => 'audio', 240 'groups' => array('audio'), 'string' => 'audio'), 241 'rar' => array('type' => 'application/x-rar-compressed', 'icon' => 'archive', 242 'groups' => array('archive'), 'string' => 'archive'), 243 'rhb' => array('type' => 'text/xml', 'icon' => 'markup'), 244 'rm' => array('type' => 'audio/x-pn-realaudio-plugin', 'icon' => 'audio', 245 'groups' => array('audio'), 'string' => 'audio'), 246 'rmvb' => array('type' => 'application/vnd.rn-realmedia-vbr', 'icon' => 'video', 247 'groups' => array('video'), 'string' => 'video'), 248 'rtf' => array('type' => 'text/rtf', 'icon' => 'text', 'groups' => array('document')), 249 'rtx' => array('type' => 'text/richtext', 'icon' => 'text'), 250 'rv' => array('type' => 'audio/x-pn-realaudio-plugin', 'icon' => 'audio', 251 'groups' => array('video'), 'string' => 'video'), 252 'scss' => array('type' => 'text/x-scss', 'icon' => 'json', 'groups' => array('web_file')), 253 'sh' => array('type' => 'application/x-sh', 'icon' => 'sourcecode'), 254 'sit' => array('type' => 'application/x-stuffit', 'icon' => 'archive', 255 'groups' => array('archive'), 'string' => 'archive'), 256 'smi' => array('type' => 'application/smil', 'icon' => 'text'), 257 'smil' => array('type' => 'application/smil', 'icon' => 'text'), 258 'sqt' => array('type' => 'text/xml', 'icon' => 'markup'), 259 'svg' => array('type' => 'image/svg+xml', 'icon' => 'image', 260 'groups' => array('image', 'web_image'), 'string' => 'image'), 261 'svgz' => array('type' => 'image/svg+xml', 'icon' => 'image', 262 'groups' => array('image', 'web_image'), 'string' => 'image'), 263 'swa' => array('type' => 'application/x-director', 'icon' => 'flash'), 264 'swf' => array('type' => 'application/x-shockwave-flash', 'icon' => 'flash'), 265 'swfl' => array('type' => 'application/x-shockwave-flash', 'icon' => 'flash'), 266 267 'sxw' => array('type' => 'application/vnd.sun.xml.writer', 'icon' => 'writer'), 268 'stw' => array('type' => 'application/vnd.sun.xml.writer.template', 'icon' => 'writer'), 269 'sxc' => array('type' => 'application/vnd.sun.xml.calc', 'icon' => 'calc'), 270 'stc' => array('type' => 'application/vnd.sun.xml.calc.template', 'icon' => 'calc'), 271 'sxd' => array('type' => 'application/vnd.sun.xml.draw', 'icon' => 'draw'), 272 'std' => array('type' => 'application/vnd.sun.xml.draw.template', 'icon' => 'draw'), 273 'sxi' => array('type' => 'application/vnd.sun.xml.impress', 'icon' => 'impress', 'groups' => array('presentation')), 274 'sti' => array('type' => 'application/vnd.sun.xml.impress.template', 'icon' => 'impress', 275 'groups' => array('presentation')), 276 'sxg' => array('type' => 'application/vnd.sun.xml.writer.global', 'icon' => 'writer'), 277 'sxm' => array('type' => 'application/vnd.sun.xml.math', 'icon' => 'math'), 278 279 'tar' => array('type' => 'application/x-tar', 'icon' => 'archive', 'groups' => array('archive'), 'string' => 'archive'), 280 'tif' => array('type' => 'image/tiff', 'icon' => 'image', 'groups' => array('image'), 'string' => 'image'), 281 'tiff' => array('type' => 'image/tiff', 'icon' => 'image', 'groups' => array('image'), 'string' => 'image'), 282 'tex' => array('type' => 'application/x-tex', 'icon' => 'text'), 283 'texi' => array('type' => 'application/x-texinfo', 'icon' => 'text'), 284 'texinfo' => array('type' => 'application/x-texinfo', 'icon' => 'text'), 285 'ts' => array('type' => 'video/MP2T', 'icon' => 'video', 'groups' => array('video', 'web_video'), 286 'string' => 'video'), 287 'tsv' => array('type' => 'text/tab-separated-values', 'icon' => 'text'), 288 'txt' => array('type' => 'text/plain', 'icon' => 'text', 'defaulticon' => true), 289 'vtt' => array('type' => 'text/vtt', 'icon' => 'text', 'groups' => array('html_track')), 290 'wav' => array('type' => 'audio/wav', 'icon' => 'audio', 'groups' => array('audio', 'html_audio', 'web_audio'), 291 'string' => 'audio'), 292 'webm' => array('type' => 'video/webm', 'icon' => 'video', 'groups' => array('html_video', 'video', 'web_video'), 293 'string' => 'video'), 294 'wmv' => array('type' => 'video/x-ms-wmv', 'icon' => 'video', 'groups' => array('video'), 'string' => 'video'), 295 'asf' => array('type' => 'video/x-ms-asf', 'icon' => 'video', 'groups' => array('video'), 'string' => 'video'), 296 'wma' => array('type' => 'audio/x-ms-wma', 'icon' => 'audio', 'groups' => array('audio'), 'string' => 'audio'), 297 298 'xbk' => array('type' => 'application/x-smarttech-notebook', 'icon' => 'archive'), 299 'xdp' => array('type' => 'application/vnd.adobe.xdp+xml', 'icon' => 'pdf'), 300 'xfd' => array('type' => 'application/vnd.xfdl', 'icon' => 'pdf'), 301 'xfdf' => array('type' => 'application/vnd.adobe.xfdf', 'icon' => 'pdf'), 302 303 'xls' => array('type' => 'application/vnd.ms-excel', 'icon' => 'spreadsheet', 'groups' => array('spreadsheet')), 304 'xlsx' => array('type' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'icon' => 'spreadsheet', 305 'groups' => array('spreadsheet')), 306 'xlsm' => array('type' => 'application/vnd.ms-excel.sheet.macroEnabled.12', 307 'icon' => 'spreadsheet', 'groups' => array('spreadsheet')), 308 'xltx' => array('type' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.template', 309 'icon' => 'spreadsheet'), 310 'xltm' => array('type' => 'application/vnd.ms-excel.template.macroEnabled.12', 'icon' => 'spreadsheet'), 311 'xlsb' => array('type' => 'application/vnd.ms-excel.sheet.binary.macroEnabled.12', 'icon' => 'spreadsheet'), 312 'xlam' => array('type' => 'application/vnd.ms-excel.addin.macroEnabled.12', 'icon' => 'spreadsheet'), 313 314 'xml' => array('type' => 'application/xml', 'icon' => 'markup'), 315 'xsl' => array('type' => 'text/xml', 'icon' => 'markup'), 316 317 'yaml' => array('type' => 'application/yaml', 'icon' => 'markup'), 318 'yml' => array('type' => 'application/yaml', 'icon' => 'markup'), 319 320 'zip' => array('type' => 'application/zip', 'icon' => 'archive', 'groups' => array('archive'), 'string' => 'archive') 321 ); 322 } 323 324 /** 325 * Given a mimetype - return a valid file extension for it. 326 * 327 * @param $mimetype string 328 * @return string|bool False if the mimetype was not known, a string indicating a valid file extension otherwise. It may not 329 * be the only valid file extension - just the first one found. 330 */ 331 public static function get_file_extension($mimetype) { 332 $types = self::get_types(); 333 foreach ($types as $extension => $info) { 334 if ($info['type'] == $mimetype) { 335 return $extension; 336 } 337 } 338 return false; 339 } 340 341 /** 342 * Gets all the current types. 343 * 344 * @return array Associative array from extension to array of data about type 345 */ 346 public static function &get_types() { 347 // If it was already done in this request, use cache. 348 if (self::$cachedtypes) { 349 return self::$cachedtypes; 350 } 351 352 // Get defaults. 353 $mimetypes = self::get_default_types(); 354 355 // Get custom file types. 356 $custom = self::get_custom_types(); 357 358 // Check value is an array. 359 if (!is_array($custom)) { 360 debugging('Invalid $CFG->customfiletypes (not array)', DEBUG_DEVELOPER); 361 $custom = array(); 362 } 363 364 foreach ($custom as $customentry) { 365 // Each entry is a stdClass object similar to the array values above. 366 if (empty($customentry->extension)) { 367 debugging('Invalid $CFG->customfiletypes entry (extension field required)', 368 DEBUG_DEVELOPER); 369 continue; 370 } 371 372 // To delete a standard entry, set 'deleted' to true. 373 if (!empty($customentry->deleted)) { 374 unset($mimetypes[$customentry->extension]); 375 continue; 376 } 377 378 // Check required fields. 379 if (empty($customentry->type) || empty($customentry->icon)) { 380 debugging('Invalid $CFG->customfiletypes entry ' . $customentry->extension . 381 ' (type and icon fields required)', DEBUG_DEVELOPER); 382 continue; 383 } 384 385 // Build result array. 386 $result = array('type' => $customentry->type, 'icon' => $customentry->icon); 387 if (!empty($customentry->groups)) { 388 if (!is_array($customentry->groups)) { 389 debugging('Invalid $CFG->customfiletypes entry ' . $customentry->extension . 390 ' (groups field not array)', DEBUG_DEVELOPER); 391 continue; 392 } 393 $result['groups'] = $customentry->groups; 394 } 395 if (!empty($customentry->string)) { 396 if (!is_string($customentry->string)) { 397 debugging('Invalid $CFG->customfiletypes entry ' . $customentry->extension . 398 ' (string field not string)', DEBUG_DEVELOPER); 399 continue; 400 } 401 $result['string'] = $customentry->string; 402 } 403 if (!empty($customentry->defaulticon)) { 404 if (!is_bool($customentry->defaulticon)) { 405 debugging('Invalid $CFG->customfiletypes entry ' . $customentry->extension . 406 ' (defaulticon field not bool)', DEBUG_DEVELOPER); 407 continue; 408 } 409 $result['defaulticon'] = $customentry->defaulticon; 410 } 411 if (!empty($customentry->customdescription)) { 412 if (!is_string($customentry->customdescription)) { 413 debugging('Invalid $CFG->customfiletypes entry ' . $customentry->extension . 414 ' (customdescription field not string)', DEBUG_DEVELOPER); 415 continue; 416 } 417 // As the name suggests, this field is used only for custom entries. 418 $result['customdescription'] = $customentry->customdescription; 419 } 420 421 // Track whether it is a custom filetype or a modified existing 422 // filetype. 423 if (array_key_exists($customentry->extension, $mimetypes)) { 424 $result['modified'] = true; 425 } else { 426 $result['custom'] = true; 427 } 428 429 // Add result array to list. 430 $mimetypes[$customentry->extension] = $result; 431 } 432 433 self::$cachedtypes = $mimetypes; 434 return self::$cachedtypes; 435 } 436 437 /** 438 * Gets custom types from config variable, after decoding the JSON if required. 439 * 440 * @return array Array of custom types (empty array if none) 441 */ 442 protected static function get_custom_types() { 443 global $CFG; 444 if (!empty($CFG->customfiletypes)) { 445 if (is_array($CFG->customfiletypes)) { 446 // You can define this as an array in config.php... 447 return $CFG->customfiletypes; 448 } else { 449 // Or as a JSON string in the config table. 450 return json_decode($CFG->customfiletypes); 451 } 452 } else { 453 return array(); 454 } 455 } 456 457 /** 458 * Sets the custom types into config variable, encoding into JSON. 459 * 460 * @param array $types Array of custom types 461 * @throws coding_exception If the custom types are fixed in config.php. 462 */ 463 protected static function set_custom_types(array $types) { 464 global $CFG; 465 // Check the setting hasn't been forced. 466 if (array_key_exists('customfiletypes', $CFG->config_php_settings)) { 467 throw new coding_exception('Cannot set custom filetypes because they ' . 468 'are defined in config.php'); 469 } 470 if (empty($types)) { 471 unset_config('customfiletypes'); 472 } else { 473 set_config('customfiletypes', json_encode(array_values($types))); 474 } 475 476 // Clear the cached type list. 477 self::reset_caches(); 478 } 479 480 /** 481 * Clears the type cache. This is not needed in normal use as the 482 * set_custom_types function automatically clears the cache. Intended for 483 * use in unit tests. 484 */ 485 public static function reset_caches() { 486 self::$cachedtypes = null; 487 } 488 489 /** 490 * Gets the default types that have been deleted. Returns an array containing 491 * the defaults of all those types. 492 * 493 * @return array Array (same format as get_mimetypes_array) 494 */ 495 public static function get_deleted_types() { 496 $defaults = self::get_default_types(); 497 $deleted = array(); 498 foreach (self::get_custom_types() as $customentry) { 499 if (!empty($customentry->deleted)) { 500 $deleted[$customentry->extension] = $defaults[$customentry->extension]; 501 } 502 } 503 return $deleted; 504 } 505 506 /** 507 * Adds a new entry to the list of custom filetypes. 508 * 509 * @param string $extension File extension without dot, e.g. 'doc' 510 * @param string $mimetype MIME type e.g. 'application/msword' 511 * @param string $coreicon Core icon to use e.g. 'document' 512 * @param array $groups Array of group strings that this type belongs to 513 * @param string $corestring Custom lang string name in mimetypes.php 514 * @param string $customdescription Custom description (plain text/multilang) 515 * @param bool $defaulticon True if this should be the default icon for the type 516 * @throws coding_exception If the extension already exists, or otherwise invalid 517 */ 518 public static function add_type($extension, $mimetype, $coreicon, 519 array $groups = array(), $corestring = '', $customdescription = '', 520 $defaulticon = false) { 521 // Check for blank extensions or incorrectly including the dot. 522 $extension = (string)$extension; 523 if ($extension === '' || $extension[0] === '.') { 524 throw new coding_exception('Invalid extension .' . $extension); 525 } 526 527 // Check extension not already used. 528 $mimetypes = get_mimetypes_array(); 529 if (array_key_exists($extension, $mimetypes)) { 530 throw new coding_exception('Extension ' . $extension . ' already exists'); 531 } 532 533 // For default icon, check there isn't already something with default icon 534 // set for that MIME type. 535 if ($defaulticon) { 536 foreach ($mimetypes as $type) { 537 if ($type['type'] === $mimetype && !empty($type['defaulticon'])) { 538 throw new coding_exception('MIME type ' . $mimetype . 539 ' already has a default icon set'); 540 } 541 } 542 } 543 544 // Get existing custom filetype list. 545 $customs = self::get_custom_types(); 546 547 // Check if there's a 'deleted' entry for the extension, if so then get 548 // rid of it. 549 foreach ($customs as $key => $custom) { 550 if ($custom->extension === $extension) { 551 unset($customs[$key]); 552 } 553 } 554 555 // Set up config record for new type. 556 $newtype = self::create_config_record($extension, $mimetype, $coreicon, $groups, 557 $corestring, $customdescription, $defaulticon); 558 559 // See if there's a default value with this extension. 560 $needsadding = true; 561 $defaults = self::get_default_types(); 562 if (array_key_exists($extension, $defaults)) { 563 // If it has the same values, we don't need to add it. 564 $defaultvalue = $defaults[$extension]; 565 $modified = (array)$newtype; 566 unset($modified['extension']); 567 ksort($defaultvalue); 568 ksort($modified); 569 if ($modified === $defaultvalue) { 570 $needsadding = false; 571 } 572 } 573 574 // Add to array and set in config. 575 if ($needsadding) { 576 $customs[] = $newtype; 577 } 578 self::set_custom_types($customs); 579 } 580 581 /** 582 * Updates an entry in the list of filetypes in config. 583 * 584 * @param string $extension File extension without dot, e.g. 'doc' 585 * @param string $newextension New file extension (same if not changing) 586 * @param string $mimetype MIME type e.g. 'application/msword' 587 * @param string $coreicon Core icon to use e.g. 'document' 588 * @param array $groups Array of group strings that this type belongs to 589 * @param string $corestring Custom lang string name in mimetypes.php 590 * @param string $customdescription Custom description (plain text/multilang) 591 * @param bool $defaulticon True if this should be the default icon for the type 592 * @throws coding_exception If the new extension already exists, or otherwise invalid 593 */ 594 public static function update_type($extension, $newextension, $mimetype, $coreicon, 595 array $groups = array(), $corestring = '', $customdescription = '', 596 $defaulticon = false) { 597 598 // Extension must exist. 599 $extension = (string)$extension; 600 $mimetypes = get_mimetypes_array(); 601 if (!array_key_exists($extension, $mimetypes)) { 602 throw new coding_exception('Extension ' . $extension . ' not found'); 603 } 604 605 // If there's a new extension then this must not exist. 606 $newextension = (string)$newextension; 607 if ($newextension !== $extension) { 608 if ($newextension === '' || $newextension[0] === '.') { 609 throw new coding_exception('Invalid extension .' . $newextension); 610 } 611 if (array_key_exists($newextension, $mimetypes)) { 612 throw new coding_exception('Extension ' . $newextension . ' already exists'); 613 } 614 } 615 616 // For default icon, check there isn't already something with default icon 617 // set for that MIME type (unless it's this). 618 if ($defaulticon) { 619 foreach ($mimetypes as $ext => $type) { 620 if ($ext !== $extension && $type['type'] === $mimetype && 621 !empty($type['defaulticon'])) { 622 throw new coding_exception('MIME type ' . $mimetype . 623 ' already has a default icon set'); 624 } 625 } 626 } 627 628 // Delete the old extension and then add the new one (may be same). This 629 // will correctly handle cases when a default type is involved. 630 self::delete_type($extension); 631 self::add_type($newextension, $mimetype, $coreicon, $groups, $corestring, 632 $customdescription, $defaulticon); 633 } 634 635 /** 636 * Deletes a file type from the config list (or, for a standard one, marks it 637 * as deleted). 638 * 639 * @param string $extension File extension without dot, e.g. 'doc' 640 * @throws coding_exception If the extension does not exist, or otherwise invalid 641 */ 642 public static function delete_type($extension) { 643 // Extension must exist. 644 $mimetypes = get_mimetypes_array(); 645 if (!array_key_exists($extension, $mimetypes)) { 646 throw new coding_exception('Extension ' . $extension . ' not found'); 647 } 648 649 // Get existing custom filetype list. 650 $customs = self::get_custom_types(); 651 652 // Remove any entries for this extension. 653 foreach ($customs as $key => $custom) { 654 if ($custom->extension === $extension && empty($custom->deleted)) { 655 unset($customs[$key]); 656 } 657 } 658 659 // If it was a standard entry (doesn't have 'custom' set) then add a 660 // deleted marker. 661 if (empty($mimetypes[$extension]['custom'])) { 662 $customs[] = (object)array('extension' => $extension, 'deleted' => true); 663 } 664 665 // Save and reset cache. 666 self::set_custom_types($customs); 667 } 668 669 /** 670 * Reverts a file type to the default. May only be called on types that have 671 * default values. This will undelete the type if necessary or set its values. 672 * If the type is already at default values, does nothing. 673 * 674 * @param string $extension File extension without dot, e.g. 'doc' 675 * @return bool True if anything was changed, false if it was already default 676 * @throws coding_exception If the extension is not a default type. 677 */ 678 public static function revert_type_to_default($extension) { 679 $extension = (string)$extension; 680 681 // Check it actually is a default type. 682 $defaults = self::get_default_types(); 683 if (!array_key_exists($extension, $defaults)) { 684 throw new coding_exception('Extension ' . $extension . ' is not a default type'); 685 } 686 687 // Loop through all the custom settings. 688 $changed = false; 689 $customs = self::get_custom_types(); 690 foreach ($customs as $key => $customentry) { 691 if ($customentry->extension === $extension) { 692 unset($customs[$key]); 693 $changed = true; 694 } 695 } 696 697 // Save changes if any. 698 if ($changed) { 699 self::set_custom_types($customs); 700 } 701 return $changed; 702 } 703 704 /** 705 * Converts function parameters into a record for storing in the JSON value. 706 * 707 * @param string $extension File extension without dot, e.g. 'doc' 708 * @param string $mimetype MIME type e.g. 'application/msword' 709 * @param string $coreicon Core icon to use e.g. 'document' 710 * @param array $groups Array of group strings that this type belongs to 711 * @param string $corestring Custom lang string name in mimetypes.php 712 * @param string $customdescription Custom description (plain text/multilang) 713 * @param bool $defaulticon True if this should be the default icon for the type 714 * @return stdClass Record matching the parameters 715 */ 716 protected static function create_config_record($extension, $mimetype, 717 $coreicon, array $groups, $corestring, $customdescription, $defaulticon) { 718 // Construct new entry. 719 $newentry = (object)array('extension' => (string)$extension, 'type' => (string)$mimetype, 720 'icon' => (string)$coreicon); 721 if ($groups) { 722 if (!is_array($groups)) { 723 throw new coding_exception('Groups must be an array'); 724 } 725 foreach ($groups as $group) { 726 if (!is_string($group)) { 727 throw new coding_exception('Groups must be an array of strings'); 728 } 729 } 730 $newentry->groups = $groups; 731 } 732 if ($corestring) { 733 $newentry->string = (string)$corestring; 734 } 735 if ($customdescription) { 736 $newentry->customdescription = (string)$customdescription; 737 } 738 if ($defaulticon) { 739 $newentry->defaulticon = true; 740 } 741 return $newentry; 742 } 743 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body