Location: PHPKode > projects > Aukyla Platform > aukyla/doc/html/a00225.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
  <head>
    <title>Aukyla PHP Framework</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <link rel="StyleSheet" href="auton.css" type="text/css" media="screen">
  </head>

  <body>
    <div id="mainmenu">
      <a href="http://www.auton.nl/" class="home">Home</a>
    </div>
    <div id="submenu">
      <a class="logo" href="http://www.auton.nl/"></a>

      <div class="head">Ads</div>
      <a href="http://sourceforge.net/"><img src="http://sourceforge.net/sflogo.php?group_id=116358&amp;type=1" alt="SourceForge.net Logo" style="padding: 2px 4px; width: 88px; height: 31px; border: 0px"></a>
      <a href="http://getfirefox.com/" title="Get Firefox - The Browser, Reloaded."><img src="http://www.mozilla.org/products/firefox/buttons/getfirefox_small.png" alt="Get Firefox" style="width: 110px; height: 32px; border: 0px"></a>
    </div>
    <div id="main">
<!-- Generated by Doxygen 1.3.9.1 -->
<div class="qindex"><a class="qindex" href="index.html">Main&nbsp;Page</a> | <a class="qindex" href="hierarchy.html">Class&nbsp;Hierarchy</a> | <a class="qindex" href="classes.html">Alphabetical&nbsp;List</a> | <a class="qindex" href="annotated.html">Class&nbsp;List</a> | <a class="qindex" href="files.html">File&nbsp;List</a> | <a class="qindex" href="functions.html">Class&nbsp;Members</a> | <a class="qindex" href="pages.html">Related&nbsp;Pages</a></div>
<div class="nav">
<a class="el" href="dir_000000.html">base</a></div>
<h1>MIME.php</h1><div class="fragment"><pre class="fragment">00001 &lt;?php
00002 <span class="comment">/*</span>
00003 <span class="comment">     MIME.php, provides functions for determining MIME types and getting info</span>
00004 <span class="comment">               about MIME types</span>
00005 <span class="comment">     Copyright (C) 2003-2004 Arend van Beelen, Auton Rijnsburg</span>
00006 <span class="comment"></span>
00007 <span class="comment">     This program is free software; you can redistribute it and/or modify it</span>
00008 <span class="comment">     under the terms of the GNU General Public License as published by the Free</span>
00009 <span class="comment">     Software Foundation; either version 2 of the License, or (at your option)</span>
00010 <span class="comment">     any later version.</span>
00011 <span class="comment"></span>
00012 <span class="comment">     This program is distributed in the hope that it will be useful, but WITHOUT</span>
00013 <span class="comment">     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or</span>
00014 <span class="comment">     FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for</span>
00015 <span class="comment">     more details.</span>
00016 <span class="comment"></span>
00017 <span class="comment">     You should have received a copy of the GNU General Public License along</span>
00018 <span class="comment">     with this program; if not, write to the Free Software Foundation, Inc.,</span>
00019 <span class="comment">     59 Temple Place, Suite 330, Boston, MA 02111-1307 USA</span>
00020 <span class="comment"></span>
00021 <span class="comment">     For any questions, comments or whatever, you may mail me at: hide@address.com</span>
00022 <span class="comment">*/</span>
00023 
00024 require_once('<a class="code" href="a00119.html">Locale</a>.php');
00025 require_once('<a class="code" href="a00129.html">Messages</a>.php');
00026 require_once('<a class="code" href="a00163.html">URI</a>.php');
00027 
00031 <span class="keyword">class </span>MIME
00032 {
00033         function __construct()
00034         {
00035                 $this-&gt;XDG_DATA_DIRS = explode(<span class="charliteral">':'</span>, (isset($_ENV['XDG_DATA_DIRS']) ? $_ENV['XDG_DATA_DIRS'] : '/usr/local/share/:/usr/share/'));
00036         }
00037 
00056         <span class="keyword">static</span> function type($uri, $openFile = <span class="keyword">true</span>, $useMetaData = <span class="keyword">true</span>)
00057         {
00058                 global $MIME;
00059 
00060                 <span class="keywordflow">if</span>($useMetaData == <span class="keyword">true</span> &amp;&amp; $openFile == <span class="keyword">true</span>)
00061                 {
00062                         $mimetype = <a class="code" href="a00163.html#e33">URI::metaData</a>($uri, 'mime-type');
00063 
00064                         <span class="keywordflow">if</span>($mimetype !== <span class="keyword">false</span> &amp;&amp; $mimetype !== '')
00065                         {
00066                                 <span class="keywordflow">return</span> $mimetype;
00067                         }
00068                 }
00069 
00070                 $mimetype = '';
00071                 $matchlen = 0;
00072 
00073                 $basename = basename($uri);
00074 
00075                 $MIME-&gt;loadGlobFile();
00076 
00077                 <span class="comment">// check the globs twice (both case sensitive and insensitive)</span>
00078                 <span class="keywordflow">for</span>($i = 0; $i &lt; 2; $i++)
00079                 {
00080                         <span class="comment">// walk through the file line by line</span>
00081                         foreach($MIME-&gt;globFileLines as $line)
00082                         {
00083                                 <span class="comment">// check whether the line is a comment and is valid</span>
00084                                 <span class="keywordflow">if</span>($line{0} == <span class="charliteral">'#'</span> || strstr($line, <span class="charliteral">':'</span>) === <span class="keyword">false</span>)
00085                                 {
00086                                         <span class="keywordflow">continue</span>;
00087                                 }
00088 
00089                                 <span class="comment">// strip the newline character, but leave any spaces</span>
00090                                 $line = substr($line, 0, strlen($line) - 1);
00091 
00092                                 list($mime, $glob) = explode(<span class="charliteral">':'</span>, $line, 2);
00093 
00094                                 <span class="comment">// check for a possible direct match</span>
00095                                 <span class="keywordflow">if</span>($basename == $glob)
00096                                 {
00097                                         <span class="keywordflow">return</span> $mime;
00098                                 }
00099 
00100                                 <span class="comment">// match the globs</span>
00101                                 $flag = ($i &gt; 0 ? FNM_CASEFOLD : 0);
00102                                 <span class="keywordflow">if</span>(fnmatch($glob, $basename, $flag) == <span class="keyword">true</span> &amp;&amp; strlen($glob) &gt; $matchlen)
00103                                 {
00104                                         $mimetype = $mime;
00105                                         $matchlen = strlen($glob);
00106                                 }
00107                         }
00108                 }
00109 
00110                 <span class="comment">// check for hits</span>
00111                 <span class="keywordflow">if</span>($mimetype != '')
00112                 {
00113                         <span class="keywordflow">return</span> $mimetype;
00114                 }
00115 
00116                 <span class="comment">// if globbing didn't return any results we're going to do some magic</span>
00117                 <span class="comment">// quit now if we may not or cannot open the file</span>
00118                 <span class="keywordflow">if</span>($openFile == <span class="keyword">false</span> || ($fp = <a class="code" href="a00163.html#e2">URI::fopen</a>($uri, <span class="charliteral">'r'</span>)) == <span class="keyword">false</span>)
00119                 {
00120                         <span class="keywordflow">return</span> '';
00121                 }
00122 
00123                 <span class="comment">// load the magic files if they weren't loaded yet</span>
00124                 <span class="keywordflow">if</span>(!isset($MIME-&gt;magicRules))
00125                 {
00126                         $MIME-&gt;magicRules = array();
00127 
00128                         <span class="comment">// go through the data dirs to search for the magic files</span>
00129                         foreach(array_reverse($MIME-&gt;XDG_DATA_DIRS) as $dir)
00130                         {
00131                                 <span class="comment">// read the file</span>
00132                                 <span class="keywordflow">if</span>(!file_exists(<span class="stringliteral">"$dir/mime/magic"</span>) ||
00133                                    ($buffer = file_get_contents(<span class="stringliteral">"$dir/mime/magic"</span>)) === <span class="keyword">false</span>)
00134                                 {
00135                                         <span class="keywordflow">continue</span>;
00136                                 }
00137 
00138                                 <span class="comment">// check the file type</span>
00139                                 <span class="keywordflow">if</span>(substr($buffer, 0, 12) != <span class="stringliteral">"MIME-Magic\0\n"</span>)
00140                                 {
00141                                         <span class="keywordflow">continue</span>;
00142                                 }
00143 
00144                                 $buffer = substr($buffer, 12);
00145 
00146                                 <span class="comment">// go through the entire file</span>
00147                                 <span class="keywordflow">while</span>($buffer != '')
00148                                 {
00149                                         <span class="keywordflow">if</span>($buffer{0} != <span class="charliteral">'['</span> &amp;&amp; $buffer{0} != <span class="charliteral">'&gt;'</span> &amp;&amp;
00150                                            ($buffer{0} &lt; <span class="charliteral">'0'</span> || $buffer{0} &gt; <span class="charliteral">'9'</span>))
00151                                         {
00152                                                 <span class="keywordflow">break</span>;
00153                                         }
00154 
00155                                         <span class="keywordflow">switch</span>($buffer{0})
00156                                         {
00157                                                 <span class="comment">// create an entry for a new mimetype</span>
00158                                                 <span class="keywordflow">case</span> <span class="charliteral">'['</span>:
00159                                                         $mime = substr($buffer, 1, strpos($buffer, <span class="charliteral">']'</span>) - 1);
00160                                                         $MIME-&gt;magicRules[$mime] = array();
00161                                                         $parents[0] =&amp; $MIME-&gt;magicRules[$mime];
00162                                                         $buffer = substr($buffer, strlen($mime) + 3);
00163                                                         <span class="keywordflow">break</span>;
00164 
00165                                                 <span class="comment">// add a new rule to the current mimetype</span>
00166                                                 <span class="keywordflow">case</span> <span class="charliteral">'&gt;'</span>:
00167                                                 <span class="keywordflow">default</span>:
00168                                                         $indent = ($buffer{0} == <span class="charliteral">'&gt;'</span> ? 0 : intval($buffer));
00169                                                         $buffer = substr($buffer, strpos($buffer, <span class="charliteral">'&gt;'</span>) + 1);
00170                                                         $parents[$indent][] = <span class="keyword">new</span> MIME_MagicRule;
00171                                                         $rulenum = <span class="keyword">sizeof</span>($parents[$indent]) - 1;
00172                                                         $parents[$indent][$rulenum]-&gt;start_offset = intval($buffer); $buffer = substr($buffer, strpos($buffer, <span class="charliteral">'='</span>) + 1);
00173                                                         $value_length = 256 * ord($buffer{0}) + ord($buffer{1}); $buffer = substr($buffer, 2);
00174                                                         $parents[$indent][$rulenum]-&gt;value = substr($buffer, 0, $value_length); $buffer = substr($buffer, $value_length);
00175                                                         $parents[$indent][$rulenum]-&gt;mask = ($buffer{0} != <span class="charliteral">'&amp;'</span> ? str_repeat(<span class="stringliteral">"\xff"</span>, $value_length) : substr($buffer, 1, $value_length)); <span class="keywordflow">if</span>($buffer{0} == <span class="charliteral">'&amp;'</span>) $buffer = substr($buffer, $value_length + 1);
00176                                                         $parents[$indent][$rulenum]-&gt;word_size = ($buffer{0} != <span class="charliteral">'~'</span> ? 1 : intval(substr($buffer, 1))); <span class="keywordflow">while</span>($buffer{0} != <span class="charliteral">'+'</span> &amp;&amp; $buffer{0} != <span class="stringliteral">"\n"</span> &amp;&amp; $buffer != '') $buffer = substr($buffer, 1);
00177                                                         $parents[$indent][$rulenum]-&gt;range_length = ($buffer{0} != <span class="charliteral">'+'</span> ? 1 : intval($buffer)); $buffer = substr($buffer, strpos($buffer, <span class="stringliteral">"\n"</span>) + 1);
00178                                                         $parents[$indent][$rulenum]-&gt;children = array();
00179                                                         $parents[$indent + 1] =&amp; $parents[$indent][$rulenum]-&gt;children;
00180                                                         <span class="keywordflow">break</span>;
00181                                         }
00182                                 }
00183                         }
00184 
00185                         <span class="comment">// sort the array so items with high priority will get on top</span>
00186                         ksort($MIME-&gt;magicRules);
00187                         $magicRules = array_reverse($MIME-&gt;magicRules);
00188                         reset($MIME-&gt;magicRules);
00189                 }
00190 
00191                 <span class="comment">// call the recursive function for all mime types</span>
00192                 foreach($MIME-&gt;magicRules as $mime =&gt; $rules)
00193                 {
00194                         foreach($rules as $rule)
00195                         {
00196                                 <span class="keywordflow">if</span>($MIME-&gt;applyRecursiveMagic($rule, $fp) == <span class="keyword">true</span>)
00197                                 {
00198                                         list($priority, $mimetype) = explode(<span class="charliteral">':'</span>, $mime, 2);
00199                                         <a class="code" href="a00163.html#e10">URI::fclose</a>($fp);
00200                                         <span class="keywordflow">return</span> $mimetype;
00201                                 }
00202                         }
00203                 }
00204 
00205                 <span class="comment">// nothing worked, I will now only determine whether the file is binary or text</span>
00206                 <a class="code" href="a00163.html#e7">URI::fseek</a>($fp, 0);
00207                 $length = (<a class="code" href="a00163.html#e14">URI::fileSize</a>($uri) &gt; 50 ? 50 : <a class="code" href="a00163.html#e14">URI::fileSize</a>($uri));
00208                 $data = <a class="code" href="a00163.html#e3">URI::fread</a>($fp, $length);
00209                 <a class="code" href="a00163.html#e10">URI::fclose</a>($fp);
00210                 <span class="keywordflow">for</span>($i = 0; $i &lt; strlen($data); $i++)
00211                 {
00212                         <span class="keywordflow">if</span>($data{$i} &lt; <span class="stringliteral">"\x20"</span> &amp;&amp; $data{$i} != <span class="stringliteral">"\x09"</span> &amp;&amp; $data{$i} != <span class="stringliteral">"\x0a"</span> &amp;&amp; $data{$i} != <span class="stringliteral">"\x0d"</span>)
00213                         {
00214                                 <span class="keywordflow">return</span> 'application/octet-stream';
00215                         }
00216                 }
00217                 <span class="keywordflow">return</span> 'text/plain';
00218         }
00219 
00225         <span class="keyword">private</span> function applyRecursiveMagic(MIME_MagicRule $rule, $fp)
00226         {
00227                 global $MIME;
00228 
00229                 <a class="code" href="a00163.html#e7">URI::fseek</a>($fp, $rule-&gt;start_offset);
00230                 $data = <a class="code" href="a00163.html#e3">URI::fread</a>($fp, strlen($rule-&gt;value) + $rule-&gt;range_length);
00231                 <span class="keywordflow">if</span>(strstr($data, $rule-&gt;value) !== <span class="keyword">false</span>)
00232                 {
00233                         <span class="keywordflow">if</span>(<span class="keyword">sizeof</span>($rule-&gt;children) == 0)
00234                         {
00235                                 <span class="keywordflow">return</span> <span class="keyword">true</span>;
00236                         }
00237                         <span class="keywordflow">else</span>
00238                         {
00239                                 foreach($rule-&gt;children as $child)
00240                                 {
00241                                         <span class="keywordflow">if</span>($MIME-&gt;applyRecursiveMagic($child, $fp) == <span class="keyword">true</span>)
00242                                         {
00243                                                 <span class="keywordflow">return</span> <span class="keyword">true</span>;
00244                                         }
00245                                 }
00246                         }
00247                 }
00248                 <span class="keywordflow">return</span> <span class="keyword">false</span>;
00249         }
00250 
00264         <span class="keyword">static</span> function description($mimetype, $language = '')
00265         {
00266                 global $MIME;
00267 
00268                 $MIME-&gt;description = i18n('Unknown filetype');
00269                 <span class="keywordflow">if</span>($language == '')
00270                 {
00271                         $MIME-&gt;lang = <a class="code" href="a00119.html#e1">Locale::language</a>();
00272                 }
00273                 <span class="keywordflow">else</span>
00274                 {
00275                         $MIME-&gt;lang = $language;
00276                 }
00277                 $MIME-&gt;read = <span class="keyword">false</span>;
00278 
00279                 <span class="comment">// go through the data dirs to search for the XML file for the specified mime type</span>
00280                 foreach($MIME-&gt;XDG_DATA_DIRS as $dir)
00281                 {
00282                         $filename = <span class="stringliteral">"$dir/mime/$mimetype.xml"</span>;
00283 
00284                         <span class="comment">// open the XML file</span>
00285                         <span class="keywordflow">if</span>(!file_exists($filename) ||
00286                            ($fp = fopen($filename, <span class="charliteral">'r'</span>)) == <span class="keyword">false</span>)
00287                         {
00288                                 <span class="keywordflow">continue</span>;
00289                         }
00290 
00291                         <span class="comment">// initialize XML parser</span>
00292                         $xml_parser = xml_parser_create();
00293                         xml_set_element_handler($xml_parser, array($MIME, 'description_StartElement'), array($MIME, 'description_EndElement'));
00294                         xml_set_character_data_handler($xml_parser, array($MIME, 'description_Data'));
00295 
00296                         <span class="comment">// read the file and parse</span>
00297                         <span class="keywordflow">while</span>($data = str_replace(<span class="stringliteral">"\n"</span>, <span class="stringliteral">""</span>, fread($fp, 4096)))
00298                         {
00299                                 <span class="keywordflow">if</span>(!xml_parse($xml_parser, $data, feof($fp)))
00300                                 {
00301                                         error_log(<span class="stringliteral">"ERROR: Couldn't parse $filename: "</span>.
00302                                                   xml_error_string(xml_get_error_code($xml_parser)));
00303                                         <span class="keywordflow">break</span>;
00304                                 }
00305                         }
00306                         fclose($fp);
00307                 }
00308 
00309                 <span class="keywordflow">return</span> $MIME-&gt;description;
00310         }
00311 
00315         <span class="keyword">private</span> function description_StartElement($parser, $name, $attrs)
00316         {
00317                 $this-&gt;read = <span class="keyword">false</span>;
00318                 <span class="keywordflow">if</span>($name == 'COMMENT')
00319                 {
00320                         <span class="keywordflow">if</span>(!isset($attrs['XML:LANG']) || $attrs['XML:LANG'] == $this-&gt;lang)
00321                         {
00322                                 $this-&gt;read = <span class="keyword">true</span>;
00323                         }
00324                 }
00325         }
00326 
00330         <span class="keyword">private</span> function description_EndElement($parser, $name)
00331         {
00332                 $this-&gt;read = <span class="keyword">false</span>;
00333         }
00334 
00338         <span class="keyword">private</span> function description_Data($parser, $data)
00339         {
00340                 <span class="keywordflow">if</span>($this-&gt;read == <span class="keyword">true</span>)
00341                 {
00342                         $this-&gt;description = $data;
00343                 }
00344         }
00345 
00353         <span class="keyword">static</span> function extension($mimetype)
00354         {
00355                 global $MIME;
00356 
00357                 $MIME-&gt;loadGlobFile();
00358 
00359                 foreach($MIME-&gt;globFileLines as $line)
00360                 {
00361                         <span class="keywordflow">if</span>(strstr($line, <span class="charliteral">':'</span>) === <span class="keyword">false</span>)
00362                         {
00363                                 <span class="keywordflow">continue</span>;
00364                         }
00365                         $line = trim($line);
00366                         list($mime, $glob) = explode(<span class="charliteral">':'</span>, $line, 2);
00367                         <span class="keywordflow">if</span>($mime == $mimetype)
00368                         {
00369                                 <span class="keywordflow">if</span>(substr($glob, 0, 2) == '*.')
00370                                 {
00371                                         <span class="keywordflow">return</span> substr($glob, 1);
00372                                 }
00373                         }
00374                 }
00375 
00376                 <span class="keywordflow">return</span> '';
00377         }
00378 
00379         <span class="keyword">private</span> function loadGlobFile()
00380         {
00381                 <span class="comment">// load the glob files if they haven't been loaded already</span>
00382                 <span class="keywordflow">if</span>(!isset($this-&gt;globFileLines))
00383                 {
00384                         $this-&gt;globFileLines = array();
00385 
00386                         <span class="comment">// go through the data dirs to search for the globbing files</span>
00387                         foreach($this-&gt;XDG_DATA_DIRS as $dir)
00388                         {
00389                                 <span class="comment">// read the file</span>
00390                                 <span class="keywordflow">if</span>(file_exists(<span class="stringliteral">"$dir/mime/globs"</span>) &amp;&amp;
00391                                    ($lines = file(<span class="stringliteral">"$dir/mime/globs"</span>)) !== <span class="keyword">false</span>)
00392                                 {
00393                                         $this-&gt;globFileLines = array_merge($this-&gt;globFileLines, $lines);
00394                                 }
00395                         }
00396                 }
00397         }
00398 
00399         <span class="keyword">private</span> $XDG_DATA_DIRS;
00400         <span class="keyword">private</span> $globFileLines;
00401         <span class="keyword">private</span> $magicRules;
00402         <span class="keyword">private</span> $description;
00403         <span class="keyword">private</span> $lang;
00404         <span class="keyword">private</span> $read;
00405 }
00406 
00412 <span class="keyword">class </span>MIME_MagicRule
00413 {
00414         <span class="keyword">public</span> $start_offset;
00415         <span class="keyword">public</span> $value;
00416         <span class="keyword">public</span> $mask;
00417         <span class="keyword">public</span> $word_size;
00418         <span class="keyword">public</span> $range_length;
00419         <span class="keyword">public</span> $children;
00420 }
00421 
00422 <span class="comment">// create one global instance of the class</span>
00423 global $MIME;
00424 $MIME = <span class="keyword">new</span> MIME;
00425 
00426 ?&gt;
</pre></div>    </div>
  </body>
</html>
Return current item: Aukyla Platform