| class IDF_Views_Source␊ | 
| {␊ | 
| /**␊ | 
| * Extension supported by the syntax highlighter.␊ | 
| */␊ | 
| public static $supportedExtenstions = array(␊ | 
| 'ascx', 'ashx', 'asmx', 'aspx', 'browser', 'bsh', 'c', 'cl', 'cc',␊ | 
| 'config', 'cpp', 'cs', 'csh', 'csproj', 'css', 'cv', 'cyc', 'el', 'fs',␊ | 
| 'h', 'hh', 'hpp', 'hs', 'html', 'html', 'java', 'js', 'lisp', 'master',␊ | 
| 'pas', 'perl', 'php', 'pl', 'pm', 'py', 'rb', 'scm', 'sh', 'sitemap', ␊ | 
| 'skin', 'sln', 'svc', 'vala', 'vb', 'vbproj', 'vbs', 'wsdl', 'xhtml',␊ | 
| 'xml', 'xsd', 'xsl', 'xslt');␊ | 
| ␊ | 
| /**␊ | 
| * Display help on how to checkout etc.␊ | 
| */␊ | 
| public $help_precond = array('IDF_Precondition::accessSource');␊ | 
|  | 
| if ($request_file_info->type != 'tree') {␊ | 
| $info = self::getRequestedFileMimeType($request_file_info,␊ | 
| $commit, $scm);␊ | 
| if (!self::isText($info)) {␊ | 
| if (!IDF_FileUtil::isText($info)) {␊ | 
| $rep = new Pluf_HTTP_Response($scm->getFile($request_file_info),␊ | 
| $info[0]);␊ | 
| $rep->headers['Content-Disposition'] = 'attachment; filename="'.$info[1].'"';␊ | 
|  | 
| $previous = substr($request_file, 0, -strlen($l.' '));␊ | 
| $scmConf = $request->conf->getVal('scm', 'git');␊ | 
| $props = $scm->getProperties($commit, $request_file);␊ | 
| $content = self::highLight($extra['mime'], $scm->getFile($request_file_info));␊ | 
| $content = IDF_FileUtil::highLight($extra['mime'], $scm->getFile($request_file_info));␊ | 
| return Pluf_Shortcuts_RenderToResponse('idf/source/'.$scmConf.'/file.html',␊ | 
| array(␊ | 
| 'page_title' => $page_title,␊ | 
|  | 
| */␊ | 
| public static function getRequestedFileMimeType($file_info, $commit, $scm)␊ | 
| {␊ | 
| $mime = self::getMimeType($file_info->file);␊ | 
| $mime = IDF_FileUtil::getMimeType($file_info->file);␊ | 
| if ('application/octet-stream' != $mime[0]) {␊ | 
| return $mime;␊ | 
| }␊ | 
| return self::getMimeTypeFromContent($file_info->file,␊ | 
| $scm->getFile($file_info));␊ | 
| }␊ | 
| ␊ | 
| /**␊ | 
| * Find the mime type of a file using the fileinfo class.␊ | 
| *␊ | 
| * @param string Filename/Filepath␊ | 
| * @param string File content␊ | 
| * @return array Mime type found or 'application/octet-stream', basename, extension␊ | 
| */␊ | 
| public static function getMimeTypeFromContent($file, $filedata)␊ | 
| {␊ | 
| $info = pathinfo($file);␊ | 
| $res = array('application/octet-stream',␊ | 
| $info['basename'],␊ | 
| isset($info['extension']) ? $info['extension'] : 'bin');␊ | 
| if (function_exists('finfo_open')) {␊ | 
| $finfo = finfo_open(FILEINFO_MIME);␊ | 
| $mime = finfo_buffer($finfo, $filedata);␊ | 
| finfo_close($finfo);␊ | 
| if ($mime) {␊ | 
| $res[0] = $mime;␊ | 
| }␊ | 
| if (!isset($info['extension']) && $mime) {␊ | 
| $res[2] = (0 === strpos($mime, 'text/')) ? 'txt' : 'bin';␊ | 
| } elseif (!isset($info['extension'])) {␊ | 
| $res[2] = 'bin';␊ | 
| }␊ | 
| }␊ | 
| return $res;␊ | 
| }␊ | 
| ␊ | 
| /**␊ | 
| * Find the mime type of a file.␊ | 
| *␊ | 
| * Use /etc/mime.types to find the type.␊ | 
| *␊ | 
| * @param string Filename/Filepath␊ | 
| * @param array  Mime type found or 'application/octet-stream', basename, extension␊ | 
| */␊ | 
| public static function getMimeType($file)␊ | 
| {␊ | 
| $src= Pluf::f('idf_mimetypes_db', '/etc/mime.types');␊ | 
| $mimes = preg_split("/\015\012|\015|\012/", file_get_contents($src));␊ | 
| $info = pathinfo($file);␊ | 
| if (isset($info['extension'])) {␊ | 
| foreach ($mimes as $mime) {␊ | 
| if ('#' != substr($mime, 0, 1)) {␊ | 
| $elts = preg_split('/ |\t/', $mime, -1, PREG_SPLIT_NO_EMPTY);␊ | 
| if (in_array($info['extension'], $elts)) {␊ | 
| return array($elts[0], $info['basename'], $info['extension']);␊ | 
| }␊ | 
| }␊ | 
| }␊ | 
| } else {␊ | 
| // we consider that if no extension and base name is all␊ | 
| // uppercase, then we have a text file.␊ | 
| if ($info['basename'] == strtoupper($info['basename'])) {␊ | 
| return array('text/plain', $info['basename'], 'txt');␊ | 
| }␊ | 
| $info['extension'] = 'bin';␊ | 
| }␊ | 
| return array('application/octet-stream', $info['basename'], $info['extension']);␊ | 
| }␊ | 
| ␊ | 
| /**␊ | 
| * Find if a given mime type is a text file.␊ | 
| * This uses the output of the self::getMimeType function.␊ | 
| *␊ | 
| * @param array (Mime type, file name, extension)␊ | 
| * @return bool Is text␊ | 
| */␊ | 
| public static function isText($fileinfo)␊ | 
| {␊ | 
| if (0 === strpos($fileinfo[0], 'text/')) {␊ | 
| return true;␊ | 
| }␊ | 
| $ext = 'mdtext php-dist h gitignore diff patch';␊ | 
| $extra_ext = trim(Pluf::f('idf_extra_text_ext', ''));␊ | 
| if (!empty($extra_ext))␊ | 
| $ext .= ' ' . $extra_ext;␊ | 
| $ext = array_merge(self::$supportedExtenstions, explode(' ' , $ext));␊ | 
| return (in_array($fileinfo[2], $ext));␊ | 
| }␊ | 
| ␊ | 
| public static function highLight($fileinfo, $content)␊ | 
| {␊ | 
| $pretty = '';␊ | 
| if (self::isSupportedExtension($fileinfo[2])) {␊ | 
| $pretty = ' prettyprint';␊ | 
| }␊ | 
| $table = array();␊ | 
| $i = 1;␊ | 
| foreach (preg_split("/\015\012|\015|\012/", $content) as $line) {␊ | 
| $table[] = '<tr class="c-line"><td class="code-lc" id="L'.$i.'"><a href="#L'.$i.'">'.$i.'</a></td>'␊ | 
| .'<td class="code mono'.$pretty.'">'.IDF_Diff::padLine(Pluf_esc($line)).'</td></tr>';␊ | 
| $i++;␊ | 
| }␊ | 
| return Pluf_Template::markSafe(implode("\n", $table));␊ | 
| }␊ | 
| ␊ | 
| /**␊ | 
| * Test if an extension is supported by the syntax highlighter.␊ | 
| *␊ | 
| * @param string The extension to test␊ | 
| * @return bool␊ | 
| */␊ | 
| public static function isSupportedExtension($extension)␊ | 
| {␊ | 
| return in_array($extension, self::$supportedExtenstions);␊ | 
| return IDF_FileUtil::getMimeTypeFromContent($file_info->file,␊ | 
| $scm->getFile($file_info));␊ | 
| }␊ | 
| ␊ | 
| /**␊ |