diff --git a/src/IDF/Diff.php b/src/IDF/Diff.php index d6abe56..f097183 100644 --- a/src/IDF/Diff.php +++ b/src/IDF/Diff.php @@ -169,8 +169,8 @@ class IDF_Diff $out = ''; foreach ($this->files as $filename=>$file) { $pretty = ''; - $fileinfo = IDF_Views_Source::getMimeType($filename); - if (IDF_Views_Source::isSupportedExtension($fileinfo[2])) { + $fileinfo = IDF_FileUtil::getMimeType($filename); + if (IDF_FileUtil::isSupportedExtension($fileinfo[2])) { $pretty = ' prettyprint'; } $out .= "\n".''."\n"; @@ -350,9 +350,9 @@ class IDF_Diff public function renderCompared($chunks, $filename) { - $fileinfo = IDF_Views_Source::getMimeType($filename); + $fileinfo = IDF_FileUtil::getMimeType($filename); $pretty = ''; - if (IDF_Views_Source::isSupportedExtension($fileinfo[2])) { + if (IDF_FileUtil::isSupportedExtension($fileinfo[2])) { $pretty = ' prettyprint'; } $out = ''; diff --git a/src/IDF/FileUtil.php b/src/IDF/FileUtil.php new file mode 100644 index 0000000..725d980 --- /dev/null +++ b/src/IDF/FileUtil.php @@ -0,0 +1,165 @@ +' + .''; + $i++; + } + return Pluf_Template::markSafe(implode("\n", $table)); + } + + /** + * 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) + { + static $mimes = null; + if ($mimes == null) { + $mimes = array(); + $src = Pluf::f('idf_mimetypes_db', '/etc/mime.types'); + $filecontent = @file_get_contents($src); + if ($filecontent !== false) { + $mimes = preg_split("/\015\012|\015|\012/", $filecontent); + } + } + + $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 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 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)); + } +} diff --git a/src/IDF/IssueFile.php b/src/IDF/IssueFile.php index 12b6375..9ecf559 100644 --- a/src/IDF/IssueFile.php +++ b/src/IDF/IssueFile.php @@ -39,9 +39,9 @@ class IDF_IssueFile extends Pluf_Model array( 'type' => 'Pluf_DB_Field_Sequence', //It is automatically added. - 'blank' => true, + 'blank' => true, ), - 'comment' => + 'comment' => array( 'type' => 'Pluf_DB_Field_Foreignkey', 'model' => 'IDF_IssueComment', @@ -49,7 +49,7 @@ class IDF_IssueFile extends Pluf_Model 'verbose' => __('comment'), 'relate_name' => 'attachment', ), - 'submitter' => + 'submitter' => array( 'type' => 'Pluf_DB_Field_Foreignkey', 'model' => 'Pluf_User', @@ -63,7 +63,7 @@ class IDF_IssueFile extends Pluf_Model 'size' => 100, 'verbose' => __('file name'), ), - 'attachment' => + 'attachment' => array( 'type' => 'Pluf_DB_Field_File', 'blank' => false, @@ -76,7 +76,7 @@ class IDF_IssueFile extends Pluf_Model 'verbose' => __('file size'), 'help_text' => 'Size in bytes.', ), - 'type' => + 'type' => array( 'type' => 'Pluf_DB_Field_Varchar', 'blank' => false, @@ -111,7 +111,7 @@ class IDF_IssueFile extends Pluf_Model $file = Pluf::f('upload_issue_path').'/'.$this->attachment; $this->filesize = filesize($file); // remove .dummy - $this->filename = substr(basename($file), 0, -6); + $this->filename = substr(basename($file), 0, -6); $img_extensions = array('jpeg', 'jpg', 'png', 'gif'); $info = pathinfo($this->filename); if (!isset($info['extension'])) $info['extension'] = ''; @@ -128,4 +128,10 @@ class IDF_IssueFile extends Pluf_Model { @unlink(Pluf::f('upload_issue_path').'/'.$this->attachment); } + + function isText() + { + $info = IDF_FileUtil::getMimeType($this->filename); + return IDF_FileUtil::isText($info); + } } diff --git a/src/IDF/Template/Markdown.php b/src/IDF/Template/Markdown.php index 3054ca8..50c9f6a 100644 --- a/src/IDF/Template/Markdown.php +++ b/src/IDF/Template/Markdown.php @@ -93,7 +93,7 @@ class IDF_Template_Markdown extends Pluf_Template_Tag $info = pathinfo($m[1]); $fileinfo = array($res->headers['Content-Type'], $m[1], isset($info['extension']) ? $info['extension'] : 'bin'); - if (!IDF_Views_Source::isText($fileinfo)) { + if (!IDF_FileUtil::isText($fileinfo)) { return $m[0]; } return $res->content; diff --git a/src/IDF/Tests/TestFileUtil.php b/src/IDF/Tests/TestFileUtil.php new file mode 100644 index 0000000..31d37e2 --- /dev/null +++ b/src/IDF/Tests/TestFileUtil.php @@ -0,0 +1,47 @@ + 'application/x-httpd-php', + 'whatever.pht' => 'application/x-httpd-php', + 'README' => 'text/plain', + ); + foreach ($files as $file => $mime) { + $m = IDF_Views_Source::getMimeType($file); + $this->assertEqual($mime, $m[0]); + } + } +} diff --git a/src/IDF/Tests/TestSource.php b/src/IDF/Tests/TestSource.php index fbe95da..8634cc3 100644 --- a/src/IDF/Tests/TestSource.php +++ b/src/IDF/Tests/TestSource.php @@ -32,19 +32,6 @@ class IDF_Tests_TestSource extends UnitTestCase parent::__construct('Test the source class.'); } - public function testGetMimeType() - { - $files = array( - 'whatever.php' => 'application/x-httpd-php', - 'whatever.pht' => 'application/x-httpd-php', - 'README' => 'text/plain', - ); - foreach ($files as $file => $mime) { - $m = IDF_Views_Source::getMimeType($file); - $this->assertEqual($mime, $m[0]); - } - } - public function testRegexCommit() { $regex = '#^/p/([\-\w]+)/source/tree/([^\/]+)/(.*)$#'; @@ -61,4 +48,4 @@ class IDF_Tests_TestSource extends UnitTestCase $this->assertEqual($res[2], $m[3]); } } -} \ No newline at end of file +} diff --git a/src/IDF/Views/Issue.php b/src/IDF/Views/Issue.php index 211e4b4..e0147fe 100644 --- a/src/IDF/Views/Issue.php +++ b/src/IDF/Views/Issue.php @@ -79,7 +79,7 @@ class IDF_Views_Issue } /** - * View the issues of a given user. + * View the issues of a given user. * * Only open issues are shown. */ @@ -201,7 +201,7 @@ class IDF_Views_Issue { $prj = $request->project; if (!isset($request->REQUEST['q']) or trim($request->REQUEST['q']) == '') { - $url = Pluf_HTTP_URL_urlForView('IDF_Views_Issue::index', + $url = Pluf_HTTP_URL_urlForView('IDF_Views_Issue::index', array($prj->shortname)); return new Pluf_HTTP_Response_Redirect($url); } @@ -263,7 +263,7 @@ class IDF_Views_Issue 'issue' => $issue, ); if ($request->method == 'POST') { - $form = new IDF_Form_IssueUpdate(array_merge($request->POST, + $form = new IDF_Form_IssueUpdate(array_merge($request->POST, $request->FILES), $params); if (!isset($request->POST['preview']) && $form->isValid()) { @@ -306,7 +306,7 @@ class IDF_Views_Issue $prj = $request->project; $attach = Pluf_Shortcuts_GetObjectOr404('IDF_IssueFile', $match[2]); $prj->inOr404($attach->get_comment()->get_issue()); - $info = IDF_Views_Source::getMimeType($attach->filename); + $info = IDF_FileUtil::getMimeType($attach->filename); $mime = 'application/octet-stream'; if (strpos($info[0], 'image/') === 0) { $mime = $info[0]; @@ -330,14 +330,14 @@ class IDF_Views_Issue $prj->inOr404($attach->get_comment()->get_issue()); // If one cannot see the attachement, redirect to the // getAttachment view. - $info = IDF_Views_Source::getMimeType($attach->filename); - if (!IDF_Views_Source::isText($info)) { + $info = IDF_FileUtil::getMimeType($attach->filename); + if (!IDF_FileUtil::isText($info)) { return $this->getAttachment($request, $match); } // Now we want to look at the file but with links back to the // issue. - $file = IDF_Views_Source::highLight($info, - file_get_contents(Pluf::f('upload_issue_path').'/'.$attach->attachment)); + $file = IDF_FileUtil::highLight($info, + file_get_contents(Pluf::f('upload_issue_path').'/'.$attach->attachment)); $title = sprintf(__('View %s'), $attach->filename); return Pluf_Shortcuts_RenderToResponse('idf/issues/attachment.html', array( @@ -406,7 +406,7 @@ class IDF_Views_Issue { $prj = $request->project; $tag = Pluf_Shortcuts_GetObjectOr404('IDF_Tag', $match[2]); - $status = $match[3]; + $status = $match[3]; if ($tag->project != $prj->id or !in_array($status, array('open', 'closed'))) { throw new Pluf_HTTP_Error404(); } @@ -414,7 +414,7 @@ class IDF_Views_Issue $title = sprintf(__('%1$s Issues with Label %2$s'), (string) $prj, (string) $tag); } else { - $title = sprintf(__('%1$s Closed Issues with Label %2$s'), + $title = sprintf(__('%1$s Closed Issues with Label %2$s'), (string) $prj, (string) $tag); } // Get stats about the open/closed issues having this tag. @@ -547,11 +547,11 @@ class IDF_Views_Issue */ function IDF_Views_Issue_SummaryAndLabels($field, $issue, $extra='') { - $edit = Pluf_HTTP_URL_urlForView('IDF_Views_Issue::view', + $edit = Pluf_HTTP_URL_urlForView('IDF_Views_Issue::view', array($issue->shortname, $issue->id)); $tags = array(); foreach ($issue->get_tags_list() as $tag) { - $url = Pluf_HTTP_URL_urlForView('IDF_Views_Issue::listLabel', + $url = Pluf_HTTP_URL_urlForView('IDF_Views_Issue::listLabel', array($issue->shortname, $tag->id, 'open')); $tags[] = sprintf('%s', $url, Pluf_esc((string) $tag)); } @@ -574,4 +574,4 @@ function IDF_Views_Issue_SummaryAndLabels($field, $issue, $extra='') function IDF_Views_Issue_ShowStatus($field, $issue, $extra='') { return Pluf_esc($issue->get_status()->name); -} \ No newline at end of file +} diff --git a/src/IDF/Views/Source.php b/src/IDF/Views/Source.php index 5817b22..ee2d680 100644 --- a/src/IDF/Views/Source.php +++ b/src/IDF/Views/Source.php @@ -32,17 +32,6 @@ Pluf::loadFunction('Pluf_Shortcuts_GetFormForModel'); 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'); @@ -211,7 +200,7 @@ class IDF_Views_Source 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].'"'; @@ -373,7 +362,7 @@ class IDF_Views_Source $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, @@ -451,121 +440,12 @@ class IDF_Views_Source */ 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[] = '' - .''; - $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)); } /** diff --git a/src/IDF/templates/idf/issues/view.html b/src/IDF/templates/idf/issues/view.html index 191909a..7c0b16b 100644 --- a/src/IDF/templates/idf/issues/view.html +++ b/src/IDF/templates/idf/issues/view.html @@ -1,8 +1,8 @@ {extends "idf/issues/base.html"} {block titleicon}{if $form} {/if}{/block} {block body} -{assign $i = 0} -{assign $nc = $comments.count()} +{assign $i = 0} +{assign $nc = $comments.count()} {foreach $comments as $c}{ashowuser 'submitter', $c.get_submitter(), $request}{assign $who = $c.get_submitter()}
 {if $i == 0} @@ -20,14 +20,13 @@ {if $attachments.count() > 0}
{/if} +{foreach $attachments as $a}
  • {$a.filename} - {$a.filesize|size}{if $a.isText()} - {trans 'view'}{/if}
  • {/foreach}{/if} {if $i> 0 and $c.changedIssue()} -
    +
    {foreach $c.changes as $w => $v} {if $w == 'su'}{trans 'Summary:'}{/if}{if $w == 'st'}{trans 'Status:'}{/if}{if $w == 'ow'}{trans 'Owner:'}{/if}{if $w == 'lb'}{trans 'Labels:'}{/if} {if $w == 'lb'}{assign $l = implode(', ', $v)}{$l}{else}{$v}{/if}
    {/foreach} -
    +
    {/if}
    {assign $i = $i + 1}{if $i == $nc and false == $form}
    @@ -119,7 +118,7 @@
    '.$i.''.IDF_Diff::padLine(Pluf_esc($line)).'
    '.$i.''.IDF_Diff::padLine(Pluf_esc($line)).'
      - | + | {trans 'Cancel'}