PageRenderTime 66ms CodeModel.GetById 28ms app.highlight 31ms RepoModel.GetById 1ms app.codeStats 0ms

/includes/functions.inc.php

http://github.com/tylerhall/simple-php-framework
PHP | 779 lines | 657 code | 73 blank | 49 comment | 117 complexity | ad65c8cb985c42895e9fda75b96d2e96 MD5 | raw file
  1<?PHP
  2
  3    function dater_utc($seconds = null) 
  4    {
  5        if($seconds === null) {
  6            $seconds = time();
  7        }
  8        $dt = new DateTime('@' . $seconds);
  9        $dt->setTimezone(new DateTimeZone('UTC'));
 10        return $dt->format('Y-m-d H:i:s');
 11    }
 12
 13	function twitterfy($str)
 14	{
 15	    // Via http://www.snipe.net/2009/09/php-twitter-clickable-links/
 16	    $str = preg_replace("#(^|[\n ])([\w]+?://[\w]+[^ \"\n\r\t< ]*)#", "\\1<a href=\"\\2\" target=\"_blank\">\\2</a>", $str);
 17	    $str = preg_replace("#(^|[\n ])((www|ftp)\.[^ \"\t\n\r< ]*)#", "\\1<a href=\"http://\\2\" target=\"_blank\">\\2</a>", $str);
 18	    $str = preg_replace("/@(\w+)/", "<a href=\"http://www.twitter.com/\\1\" target=\"_blank\">@\\1</a>", $str);
 19	    $str = preg_replace("/#(\w+)/", "<a href=\"http://search.twitter.com/search?q=\\1\" target=\"_blank\">#\\1</a>", $str);
 20	    return $str;
 21	}
 22
 23	function set_option($key, $val)
 24	{
 25		$db = Database::getDatabase();
 26		$db->query('REPLACE INTO options (`key`, `value`) VALUES (:key, :value)', array('key' => $key, 'value' => $val));
 27	}
 28
 29	function get_option($key, $default = null)
 30	{
 31		$db = Database::getDatabase();
 32		$db->query('SELECT `value` FROM options WHERE `key` = :key', array('key' => $key));
 33		if($db->hasRows())
 34			return $db->getValue();
 35		else
 36			return $default;
 37	}
 38
 39    function printr($var)
 40    {
 41        $output = print_r($var, true);
 42        $output = str_replace("\n", "<br>", $output);
 43        $output = str_replace(' ', '&nbsp;', $output);
 44        echo "<div style='font-family:courier;'>$output</div>";
 45    }
 46
 47    // Formats a given number of seconds into proper mm:ss format
 48    function format_time($seconds)
 49    {
 50        return floor($seconds / 60) . ':' . str_pad($seconds % 60, 2, '0');
 51    }
 52
 53    // Given a string such as "comment_123" or "id_57", it returns the final, numeric id.
 54    function split_id($str)
 55    {
 56        return match('/[_-]([0-9]+)$/', $str, 1);
 57    }
 58
 59    // Creates a friendly URL slug from a string
 60    function slugify($str)
 61    {
 62        $str = preg_replace('/[^a-zA-Z0-9 -]/', '', $str);
 63        $str = strtolower(str_replace(' ', '-', trim($str)));
 64        $str = preg_replace('/-+/', '-', $str);
 65        return $str;
 66    }
 67
 68    // Computes the *full* URL of the current page (protocol, server, path, query parameters, etc)
 69    function full_url()
 70    {
 71        $s = empty($_SERVER['HTTPS']) ? '' : ($_SERVER['HTTPS'] == 'on') ? 's' : '';
 72        $protocol = substr(strtolower($_SERVER['SERVER_PROTOCOL']), 0, strpos(strtolower($_SERVER['SERVER_PROTOCOL']), '/')) . $s;
 73        $port = ($_SERVER['SERVER_PORT'] == '80') ? '' : (":".$_SERVER['SERVER_PORT']);
 74        return $protocol . "://" . $_SERVER['HTTP_HOST'] . $port . $_SERVER['REQUEST_URI'];
 75    }
 76
 77    // Returns an English representation of a past date within the last month
 78    // Graciously stolen from http://ejohn.org/files/pretty.js
 79    function time2str($ts)
 80    {
 81        if(!ctype_digit($ts)) {
 82            $ts = strtotime($ts);
 83		}
 84
 85        $diff = time() - $ts;
 86        if($diff == 0) {
 87            return 'now';
 88        } else if($diff > 0) {
 89            $day_diff = floor($diff / 86400);
 90            if($day_diff == 0)
 91            {
 92                if($diff < 60) return 'just now';
 93                if($diff < 120) return '1 minute ago';
 94                if($diff < 3600) return floor($diff / 60) . ' minutes ago';
 95                if($diff < 7200) return '1 hour ago';
 96                if($diff < 86400) return floor($diff / 3600) . ' hours ago';
 97            }
 98            if($day_diff == 1) return 'Yesterday';
 99            if($day_diff < 7) return $day_diff . ' days ago';
100            if($day_diff < 31) return ceil($day_diff / 7) . ' weeks ago';
101            if($day_diff < 60) return 'last month';
102            $ret = date('F Y', $ts);
103            return ($ret == 'December 1969') ? '' : $ret;
104        } else {
105            $diff = abs($diff);
106            $day_diff = floor($diff / 86400);
107            if($day_diff == 0)
108            {
109                if($diff < 120) return 'in a minute';
110                if($diff < 3600) return 'in ' . floor($diff / 60) . ' minutes';
111                if($diff < 7200) return 'in an hour';
112                if($diff < 86400) return 'in ' . floor($diff / 3600) . ' hours';
113            }
114            if($day_diff == 1) return 'Tomorrow';
115            if($day_diff < 4) return date('l', $ts);
116            if($day_diff < 7 + (7 - date('w'))) return 'next week';
117            if(ceil($day_diff / 7) < 4) return 'in ' . ceil($day_diff / 7) . ' weeks';
118            if(date('n', $ts) == date('n') + 1) return 'next month';
119            $ret = date('F Y', $ts);
120            return ($ret == 'December 1969') ? '' : $ret;
121        }
122    }
123
124    // Returns an array representation of the given calendar month.
125    // The array values are timestamps which allow you to easily format
126    // and manipulate the dates as needed.
127    function calendar($month = null, $year = null)
128    {
129        if(is_null($month)) $month = date('n');
130        if(is_null($year)) $year = date('Y');
131
132        $first = mktime(0, 0, 0, $month, 1, $year);
133        $last = mktime(23, 59, 59, $month, date('t', $first), $year);
134
135        $start = $first - (86400 * date('w', $first));
136        $stop = $last + (86400 * (7 - date('w', $first)));
137
138        $out = array();
139        while($start < $stop)
140        {
141            $week = array();
142            if($start > $last) break;
143            for($i = 0; $i < 7; $i++)
144            {
145                $week[$i] = $start;
146                $start += 86400;
147            }
148            $out[] = $week;
149        }
150
151        return $out;
152    }
153
154    // Processes mod_rewrite URLs into key => value pairs
155    // See .htacess for more info.
156    function pick_off($grab_first = false, $sep = '/')
157    {
158        $ret = array();
159        $arr = explode($sep, trim($_SERVER['REQUEST_URI'], $sep));
160        if($grab_first) $ret[0] = array_shift($arr);
161        while(count($arr) > 0) {
162            $ret[array_shift($arr)] = array_shift($arr);
163		}
164        return (count($ret) > 0) ? $ret : false;
165    }
166
167    // Creates a list of <option>s from the given database table.
168    // table name, column to use as value, column(s) to use as text, default value(s) to select (can accept an array of values), extra sql to limit results
169    function get_options($table, $val, $text, $default = null, $sql = '')
170    {
171        $db = Database::getDatabase(true);
172        $out = '';
173
174        $table = $db->escape($table);
175        $rows = $db->getRows("SELECT * FROM `$table` $sql");
176        foreach($rows as $row)
177        {
178            $the_text = '';
179            if(!is_array($text)) $text = array($text); // Allows you to concat multiple fields for display
180            foreach($text as $t)
181                $the_text .= $row[$t] . ' ';
182            $the_text = htmlspecialchars(trim($the_text));
183
184            if(!is_null($default) && $row[$val] == $default)
185                $out .= '<option value="' . htmlspecialchars($row[$val], ENT_QUOTES) . '" selected="selected">' . $the_text . '</option>';
186            elseif(is_array($default) && in_array($row[$val],$default))
187                $out .= '<option value="' . htmlspecialchars($row[$val], ENT_QUOTES) . '" selected="selected">' . $the_text . '</option>';
188            else
189                $out .= '<option value="' . htmlspecialchars($row[$val], ENT_QUOTES) . '">' . $the_text . '</option>';
190        }
191        return $out;
192    }
193
194    // More robust strict date checking for string representations
195    function chkdate($str)
196    {
197        $info = date_parse($str);
198        if($info !== false && $info['error_count'] == 0)
199        {
200            if(checkdate($info['month'], $info['day'], $info['year'])) {
201                return true;
202			}
203        }
204
205        return false;
206    }
207
208    // Converts a date/timestamp into the specified format
209    function dater($date = null, $format = null)
210    {
211        if(is_null($format)) {
212            $format = 'Y-m-d H:i:s';
213		}
214
215        if(is_null($date)) {
216            $date = time();
217		}
218
219        // if $date contains only numbers, treat it as a timestamp
220        if(ctype_digit($date) === true)
221            return date($format, $date);
222        else
223            return date($format, strtotime($date));
224    }
225
226    // Formats a phone number as (xxx) xxx-xxxx or xxx-xxxx depending on the length.
227    function format_phone($phone)
228    {
229        $phone = preg_replace("/[^0-9]/", '', $phone);
230
231        if(strlen($phone) == 7)
232            return preg_replace("/([0-9]{3})([0-9]{4})/", "$1-$2", $phone);
233        elseif(strlen($phone) == 10)
234            return preg_replace("/([0-9]{3})([0-9]{3})([0-9]{4})/", "($1) $2-$3", $phone);
235        else
236            return $phone;
237    }
238
239    // Outputs hour, minute, am/pm dropdown boxes
240    function hourmin($hid = 'hour', $mid = 'minute', $pid = 'ampm', $hval = null, $mval = null, $pval = null)
241    {
242        // Dumb hack to let you just pass in a timestamp instead
243        if(func_num_args() == 1)
244        {
245            list($hval, $mval, $pval) = explode(' ', date('g i a', strtotime($hid)));
246            $hid = 'hour';
247            $mid = 'minute';
248            $aid = 'ampm';
249        }
250        else
251        {
252            if(is_null($hval)) $hval = date('h');
253            if(is_null($mval)) $mval = date('i');
254            if(is_null($pval)) $pval = date('a');
255        }
256
257        $hours = array(12, 1, 2, 3, 4, 5, 6, 7, 9, 10, 11);
258        $out = "<select name='$hid' id='$hid'>";
259        foreach($hours as $hour)
260            if(intval($hval) == intval($hour)) $out .= "<option value='$hour' selected>$hour</option>";
261            else $out .= "<option value='$hour'>$hour</option>";
262        $out .= "</select>";
263
264        $minutes = array('00', 15, 30, 45);
265        $out .= "<select name='$mid' id='$mid'>";
266        foreach($minutes as $minute)
267            if(intval($mval) == intval($minute)) $out .= "<option value='$minute' selected>$minute</option>";
268            else $out .= "<option value='$minute'>$minute</option>";
269        $out .= "</select>";
270
271        $out .= "<select name='$pid' id='$pid'>";
272        $out .= "<option value='am'>am</option>";
273        if($pval == 'pm') $out .= "<option value='pm' selected>pm</option>";
274        else $out .= "<option value='pm'>pm</option>";
275        $out .= "</select>";
276
277        return $out;
278    }
279
280    // Returns the HTML for a month, day, and year dropdown boxes.
281    // You can set the default date by passing in a timestamp OR a parseable date string.
282    // $prefix_ will be appened to the name/id's of each dropdown, allowing for multiple calls in the same form.
283    // $output_format lets you specify which dropdowns appear and in what order.
284    function mdy($date = null, $prefix = null, $output_format = 'm d y')
285    {
286        if(is_null($date)) $date = time();
287        if(!ctype_digit($date)) $date = strtotime($date);
288        if(!is_null($prefix)) $prefix .= '_';
289        list($yval, $mval, $dval) = explode(' ', date('Y n j', $date));
290
291        $month_dd = "<select name='{$prefix}month' id='{$prefix}month'>";
292        for($i = 1; $i <= 12; $i++)
293        {
294            $selected = ($mval == $i) ? ' selected="selected"' : '';
295            $month_dd .= "<option value='$i'$selected>" . date('F', mktime(0, 0, 0, $i, 1, 2000)) . "</option>";
296        }
297        $month_dd .= "</select>";
298
299        $day_dd = "<select name='{$prefix}day' id='{$prefix}day'>";
300        for($i = 1; $i <= 31; $i++)
301        {
302            $selected = ($dval == $i) ? ' selected="selected"' : '';
303            $day_dd .= "<option value='$i'$selected>$i</option>";
304        }
305        $day_dd .= "</select>";
306
307        $year_dd = "<select name='{$prefix}year' id='{$prefix}year'>";
308        for($i = date('Y'); $i < date('Y') + 10; $i++)
309        {
310            $selected = ($yval == $i) ? ' selected="selected"' : '';
311            $year_dd .= "<option value='$i'$selected>$i</option>";
312        }
313        $year_dd .= "</select>";
314
315        $trans = array('m' => $month_dd, 'd' => $day_dd, 'y' => $year_dd);
316        return strtr($output_format, $trans);
317    }
318
319    // Redirects user to $url
320    function redirect($url = null)
321    {
322        if(is_null($url)) $url = $_SERVER['PHP_SELF'];
323        header("Location: $url");
324        exit();
325    }
326
327    // Ensures $str ends with a single /
328    function slash($str)
329    {
330        return rtrim($str, '/') . '/';
331    }
332
333    // Ensures $str DOES NOT end with a /
334    function unslash($str)
335    {
336        return rtrim($str, '/');
337    }
338
339    // Returns an array of the values of the specified column from a multi-dimensional array
340    function gimme($arr, $key = null, $mod = 1)
341    {
342        if(is_null($key))
343            $key = current(array_keys($arr));
344
345		if(is_numeric($key)) {
346			$keys = array_keys($arr[0]);
347			$key = $keys[$key];
348		}
349
350        $out = array();
351		$i = 0;
352        foreach($arr as $k => $a)
353		{
354			if($i % $mod == 0)
355	            $out[] = $a[$key];
356			$i++;
357		}
358
359        return $out;
360    }
361
362    // Returns the first $num words of $str
363    function max_words($str, $num, $suffix = '')
364    {
365        $words = explode(' ', $str);
366        if(count($words) < $num)
367            return $str;
368        else
369            return implode(' ', array_slice($words, 0, $num)) . $suffix;
370    }
371
372    // Serves an external document for download as an HTTP attachment.
373    function download_document($filename, $mimetype = 'application/octet-stream')
374    {
375        if(!file_exists($filename) || !is_readable($filename)) return false;
376        $base = basename($filename);
377        header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
378        header("Content-Disposition: attachment; filename=$base");
379        header("Content-Length: " . filesize($filename));
380        header("Content-Type: $mimetype");
381        readfile($filename);
382        exit();
383    }
384
385    // Retrieves the filesize of a remote file.
386    function remote_filesize($url, $user = null, $pw = null)
387    {
388        $ch = curl_init($url);
389        curl_setopt($ch, CURLOPT_HEADER, 1);
390        curl_setopt($ch, CURLOPT_NOBODY, 1);
391        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
392
393        if(!is_null($user) && !is_null($pw))
394        {
395            $headers = array('Authorization: Basic ' .  base64_encode("$user:$pw"));
396            curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
397        }
398
399        $head = curl_exec($ch);
400        curl_close($ch);
401
402        preg_match('/Content-Length:\s([0-9].+?)\s/', $head, $matches);
403
404        return isset($matches[1]) ? $matches[1] : false;
405    }
406
407    // Outputs a filesize in human readable format.
408    function bytes2str($val, $round = 0)
409    {
410        $unit = array('','K','M','G','T','P','E','Z','Y');
411        while($val >= 1000)
412        {
413            $val /= 1024;
414            array_shift($unit);
415        }
416        return round($val, $round) . array_shift($unit) . 'B';
417    }
418
419    // Tests for a valid email address and optionally tests for valid MX records, too.
420    function valid_email($email, $test_mx = false)
421    {
422		list($user, $domain) = explode('@', $email);
423		if(strlen($user) > 0 && strlen($domain) > 0) {
424			$parts = explode('.', $domain);
425			if($parts >= 2) {
426	            if($test_mx) {
427	                return getmxrr($domain, $mxrecords);
428	            } else {
429	                return true;
430				}
431			}
432		}
433
434        return false;
435    }
436
437    // Grabs the contents of a remote URL. Can perform basic authentication if un/pw are provided.
438    function geturl($url, $username = null, $password = null)
439    {
440        if(function_exists('curl_init'))
441        {
442            $ch = curl_init();
443            if(!is_null($username) && !is_null($password)) {
444                curl_setopt($ch, CURLOPT_HTTPHEADER, array('Authorization: Basic ' .  base64_encode("$username:$password")));
445			}
446            curl_setopt($ch, CURLOPT_URL, $url);
447            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
448            $html = curl_exec($ch);
449            curl_close($ch);
450            return $html;
451        }
452        elseif(ini_get('allow_url_fopen') == true)
453        {
454            if(!is_null($username) && !is_null($password))
455                $url = str_replace("://", "://$username:$password@", $url);
456            $html = file_get_contents($url);
457            return $html;
458        }
459        else
460        {
461            // Cannot open url. Either install curl-php or set allow_url_fopen = true in php.ini
462            return false;
463        }
464    }
465
466    // Returns the user's browser info.
467    // browscap.ini must be available for this to work.
468    // See the PHP manual for more details.
469    function browser_info()
470    {
471        $info    = get_browser(null, true);
472        $browser = $info['browser'] . ' ' . $info['version'];
473        $os      = $info['platform'];
474        $ip      = $_SERVER['REMOTE_ADDR'];
475        return array('ip' => $ip, 'browser' => $browser, 'os' => $os);
476    }
477
478    // Quick wrapper for preg_match
479    function match($regex, $str, $i = 0)
480    {
481        if(preg_match($regex, $str, $match) == 1)
482            return $match[$i];
483        else
484            return false;
485    }
486
487    // Sends an HTML formatted email
488    function send_html_mail($to, $subject, $msg, $from, $plaintext = '')
489    {
490        if(!is_array($to)) $to = array($to);
491
492        foreach($to as $address)
493        {
494            $boundary = uniqid(rand(), true);
495
496            $headers  = "From: $from\n";
497            $headers .= "MIME-Version: 1.0\n";
498            $headers .= "Content-Type: multipart/alternative; boundary = $boundary\n";
499            $headers .= "This is a MIME encoded message.\n\n";
500            $headers .= "--$boundary\n" .
501                        "Content-Type: text/plain; charset=ISO-8859-1\n" .
502                        "Content-Transfer-Encoding: base64\n\n";
503            $headers .= chunk_split(base64_encode($plaintext));
504            $headers .= "--$boundary\n" .
505                        "Content-Type: text/html; charset=ISO-8859-1\n" .
506                        "Content-Transfer-Encoding: base64\n\n";
507            $headers .= chunk_split(base64_encode($msg));
508            $headers .= "--$boundary--\n" .
509
510            mail($address, $subject, '', $headers);
511        }
512    }
513
514    // Quick and dirty wrapper for curl scraping.
515    function curl($url, $referer = null, $post = null)
516    {
517        static $tmpfile;
518
519        if(!isset($tmpfile) || ($tmpfile == '')) $tmpfile = tempnam('/tmp', 'FOO');
520
521        $ch = curl_init($url);
522        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
523        curl_setopt($ch, CURLOPT_COOKIEFILE, $tmpfile);
524        curl_setopt($ch, CURLOPT_COOKIEJAR, $tmpfile);
525        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
526        curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_4) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.1 Safari/605.1.15");
527        // curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
528        // curl_setopt($ch, CURLOPT_VERBOSE, 1);
529
530        if(!is_null($referer)) {
531			curl_setopt($ch, CURLOPT_REFERER, $referer);
532		}
533
534        if(!is_null($post)) {
535            curl_setopt($ch, CURLOPT_POST, true);
536            curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
537        }
538
539        $html = curl_exec($ch);
540
541        // $last_url = curl_getinfo($ch, CURLINFO_EFFECTIVE_URL);
542        return $html;
543    }
544
545    // Accepts any number of arguments and returns the first non-empty one
546    function pick()
547    {
548        foreach(func_get_args() as $arg) {
549            if(!empty($arg)) {
550                return $arg;
551			}
552		}
553        return '';
554    }
555
556    // Secure a PHP script using basic HTTP authentication
557    function http_auth($un, $pw, $realm = "Secured Area")
558    {
559        if(!(isset($_SERVER['PHP_AUTH_USER']) && isset($_SERVER['PHP_AUTH_PW']) && $_SERVER['PHP_AUTH_USER'] == $un && $_SERVER['PHP_AUTH_PW'] == $pw))
560        {
561            header('WWW-Authenticate: Basic realm="' . $realm . '"');
562            header('Status: 401 Unauthorized');
563            exit();
564        }
565    }
566
567    // This is easier than typing 'echo WEB_ROOT'
568    function WEBROOT()
569    {
570        echo WEB_ROOT;
571    }
572
573    // Class Autloader
574	function spf_autoload($class_name)
575	{
576		$fn = DOC_ROOT . '/includes/class.' . strtolower($class_name) . '.php';
577		if(file_exists($fn))
578		{
579			return include $fn;
580		}
581	}
582
583    // Returns a file's mimetype based on its extension
584    function mime_type($filename, $default = 'application/octet-stream')
585    {
586        $mime_types = array('323'     => 'text/h323',
587                            'acx'     => 'application/internet-property-stream',
588                            'ai'      => 'application/postscript',
589                            'aif'     => 'audio/x-aiff',
590                            'aifc'    => 'audio/x-aiff',
591                            'aiff'    => 'audio/x-aiff',
592                            'asf'     => 'video/x-ms-asf',
593                            'asr'     => 'video/x-ms-asf',
594                            'asx'     => 'video/x-ms-asf',
595                            'au'      => 'audio/basic',
596                            'avi'     => 'video/x-msvideo',
597                            'axs'     => 'application/olescript',
598                            'bas'     => 'text/plain',
599                            'bcpio'   => 'application/x-bcpio',
600                            'bin'     => 'application/octet-stream',
601                            'bmp'     => 'image/bmp',
602                            'c'       => 'text/plain',
603                            'cat'     => 'application/vnd.ms-pkiseccat',
604                            'cdf'     => 'application/x-cdf',
605                            'cer'     => 'application/x-x509-ca-cert',
606                            'class'   => 'application/octet-stream',
607                            'clp'     => 'application/x-msclip',
608                            'cmx'     => 'image/x-cmx',
609                            'cod'     => 'image/cis-cod',
610                            'cpio'    => 'application/x-cpio',
611                            'crd'     => 'application/x-mscardfile',
612                            'crl'     => 'application/pkix-crl',
613                            'crt'     => 'application/x-x509-ca-cert',
614                            'csh'     => 'application/x-csh',
615                            'css'     => 'text/css',
616                            'dcr'     => 'application/x-director',
617                            'der'     => 'application/x-x509-ca-cert',
618                            'dir'     => 'application/x-director',
619                            'dll'     => 'application/x-msdownload',
620                            'dms'     => 'application/octet-stream',
621                            'doc'     => 'application/msword',
622                            'dot'     => 'application/msword',
623                            'dvi'     => 'application/x-dvi',
624                            'dxr'     => 'application/x-director',
625                            'eps'     => 'application/postscript',
626                            'etx'     => 'text/x-setext',
627                            'evy'     => 'application/envoy',
628                            'exe'     => 'application/octet-stream',
629                            'fif'     => 'application/fractals',
630                            'flac'    => 'audio/flac',
631                            'flr'     => 'x-world/x-vrml',
632                            'gif'     => 'image/gif',
633                            'gtar'    => 'application/x-gtar',
634                            'gz'      => 'application/x-gzip',
635                            'h'       => 'text/plain',
636                            'hdf'     => 'application/x-hdf',
637                            'hlp'     => 'application/winhlp',
638                            'hqx'     => 'application/mac-binhex40',
639                            'hta'     => 'application/hta',
640                            'htc'     => 'text/x-component',
641                            'htm'     => 'text/html',
642                            'html'    => 'text/html',
643                            'htt'     => 'text/webviewhtml',
644                            'ico'     => 'image/x-icon',
645                            'ief'     => 'image/ief',
646                            'iii'     => 'application/x-iphone',
647                            'ins'     => 'application/x-internet-signup',
648                            'isp'     => 'application/x-internet-signup',
649                            'jfif'    => 'image/pipeg',
650                            'jpe'     => 'image/jpeg',
651                            'jpeg'    => 'image/jpeg',
652                            'jpg'     => 'image/jpeg',
653                            'js'      => 'application/x-javascript',
654                            'latex'   => 'application/x-latex',
655                            'lha'     => 'application/octet-stream',
656                            'lsf'     => 'video/x-la-asf',
657                            'lsx'     => 'video/x-la-asf',
658                            'lzh'     => 'application/octet-stream',
659                            'm13'     => 'application/x-msmediaview',
660                            'm14'     => 'application/x-msmediaview',
661                            'm3u'     => 'audio/x-mpegurl',
662                            'man'     => 'application/x-troff-man',
663                            'mdb'     => 'application/x-msaccess',
664                            'me'      => 'application/x-troff-me',
665                            'mht'     => 'message/rfc822',
666                            'mhtml'   => 'message/rfc822',
667                            'mid'     => 'audio/mid',
668                            'mny'     => 'application/x-msmoney',
669                            'mov'     => 'video/quicktime',
670                            'movie'   => 'video/x-sgi-movie',
671                            'mp2'     => 'video/mpeg',
672                            'mp3'     => 'audio/mpeg',
673                            'mpa'     => 'video/mpeg',
674                            'mpe'     => 'video/mpeg',
675                            'mpeg'    => 'video/mpeg',
676                            'mpg'     => 'video/mpeg',
677                            'mpp'     => 'application/vnd.ms-project',
678                            'mpv2'    => 'video/mpeg',
679                            'ms'      => 'application/x-troff-ms',
680                            'mvb'     => 'application/x-msmediaview',
681                            'nws'     => 'message/rfc822',
682                            'oda'     => 'application/oda',
683                            'oga'     => 'audio/ogg',
684                            'ogg'     => 'audio/ogg',
685                            'ogv'     => 'video/ogg',
686                            'ogx'     => 'application/ogg',
687                            'p10'     => 'application/pkcs10',
688                            'p12'     => 'application/x-pkcs12',
689                            'p7b'     => 'application/x-pkcs7-certificates',
690                            'p7c'     => 'application/x-pkcs7-mime',
691                            'p7m'     => 'application/x-pkcs7-mime',
692                            'p7r'     => 'application/x-pkcs7-certreqresp',
693                            'p7s'     => 'application/x-pkcs7-signature',
694                            'pbm'     => 'image/x-portable-bitmap',
695                            'pdf'     => 'application/pdf',
696                            'pfx'     => 'application/x-pkcs12',
697                            'pgm'     => 'image/x-portable-graymap',
698                            'pko'     => 'application/ynd.ms-pkipko',
699                            'pma'     => 'application/x-perfmon',
700                            'pmc'     => 'application/x-perfmon',
701                            'pml'     => 'application/x-perfmon',
702                            'pmr'     => 'application/x-perfmon',
703                            'pmw'     => 'application/x-perfmon',
704                            'pnm'     => 'image/x-portable-anymap',
705                            'pot'     => 'application/vnd.ms-powerpoint',
706                            'ppm'     => 'image/x-portable-pixmap',
707                            'pps'     => 'application/vnd.ms-powerpoint',
708                            'ppt'     => 'application/vnd.ms-powerpoint',
709                            'prf'     => 'application/pics-rules',
710                            'ps'      => 'application/postscript',
711                            'pub'     => 'application/x-mspublisher',
712                            'qt'      => 'video/quicktime',
713                            'ra'      => 'audio/x-pn-realaudio',
714                            'ram'     => 'audio/x-pn-realaudio',
715                            'ras'     => 'image/x-cmu-raster',
716                            'rgb'     => 'image/x-rgb',
717                            'rmi'     => 'audio/mid',
718                            'roff'    => 'application/x-troff',
719                            'rtf'     => 'application/rtf',
720                            'rtx'     => 'text/richtext',
721                            'scd'     => 'application/x-msschedule',
722                            'sct'     => 'text/scriptlet',
723                            'setpay'  => 'application/set-payment-initiation',
724                            'setreg'  => 'application/set-registration-initiation',
725                            'sh'      => 'application/x-sh',
726                            'shar'    => 'application/x-shar',
727                            'sit'     => 'application/x-stuffit',
728                            'snd'     => 'audio/basic',
729                            'spc'     => 'application/x-pkcs7-certificates',
730                            'spl'     => 'application/futuresplash',
731                            'src'     => 'application/x-wais-source',
732                            'sst'     => 'application/vnd.ms-pkicertstore',
733                            'stl'     => 'application/vnd.ms-pkistl',
734                            'stm'     => 'text/html',
735                            'svg'     => "image/svg+xml",
736                            'sv4cpio' => 'application/x-sv4cpio',
737                            'sv4crc'  => 'application/x-sv4crc',
738                            't'       => 'application/x-troff',
739                            'tar'     => 'application/x-tar',
740                            'tcl'     => 'application/x-tcl',
741                            'tex'     => 'application/x-tex',
742                            'texi'    => 'application/x-texinfo',
743                            'texinfo' => 'application/x-texinfo',
744                            'tgz'     => 'application/x-compressed',
745                            'tif'     => 'image/tiff',
746                            'tiff'    => 'image/tiff',
747                            'tr'      => 'application/x-troff',
748                            'trm'     => 'application/x-msterminal',
749                            'tsv'     => 'text/tab-separated-values',
750                            'txt'     => 'text/plain',
751                            'uls'     => 'text/iuls',
752                            'ustar'   => 'application/x-ustar',
753                            'vcf'     => 'text/x-vcard',
754                            'vrml'    => 'x-world/x-vrml',
755                            'wav'     => 'audio/x-wav',
756                            'wcm'     => 'application/vnd.ms-works',
757                            'wdb'     => 'application/vnd.ms-works',
758                            'wks'     => 'application/vnd.ms-works',
759                            'wmf'     => 'application/x-msmetafile',
760                            'wps'     => 'application/vnd.ms-works',
761                            'wri'     => 'application/x-mswrite',
762                            'wrl'     => 'x-world/x-vrml',
763                            'wrz'     => 'x-world/x-vrml',
764                            'xaf'     => 'x-world/x-vrml',
765                            'xbm'     => 'image/x-xbitmap',
766                            'xla'     => 'application/vnd.ms-excel',
767                            'xlc'     => 'application/vnd.ms-excel',
768                            'xlm'     => 'application/vnd.ms-excel',
769                            'xls'     => 'application/vnd.ms-excel',
770                            'xlt'     => 'application/vnd.ms-excel',
771                            'xlw'     => 'application/vnd.ms-excel',
772                            'xof'     => 'x-world/x-vrml',
773                            'xpm'     => 'image/x-xpixmap',
774                            'xwd'     => 'image/x-xwindowdump',
775                            'z'       => 'application/x-compress',
776                            'zip'     => 'application/zip');
777        $ext = pathinfo($filename, PATHINFO_EXTENSION);
778        return isset($mime_types[$ext]) ? $mime_types[$ext] : $default;
779    }