PageRenderTime 7ms CodeModel.GetById 20ms app.highlight 56ms RepoModel.GetById 1ms app.codeStats 0ms

/includes/functions.inc.php

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