X-Git-Url: https://git.cweiske.de/phorkie.git/blobdiff_plain/9f4d00eb634cbf75db2143a62ce8733e901b14a8..0f0ad04504e60d8f410472232480eb1fd9332814:/src/phorkie/File.php diff --git a/src/phorkie/File.php b/src/phorkie/File.php index 7f5b5b4..97ae47e 100644 --- a/src/phorkie/File.php +++ b/src/phorkie/File.php @@ -38,6 +38,16 @@ class File return $this->path; } + /** + * Get the filename usable as HTML anchor. + * + * @return string + */ + function getAnchorName() + { + return str_replace(' ', '-', $this->getFilename()); + } + /** * Return the full path to the file * @@ -55,7 +65,7 @@ class File */ public function getExt() { - return substr($this->path, strrpos($this->path, '.') + 1); + return strtolower(substr($this->path, strrpos($this->path, '.') + 1)); } public function getContent() @@ -64,8 +74,7 @@ class File //quick hack until https://pear.php.net/bugs/bug.php?id=19385 is fixed $cmd = new GitCommandBinary($this->repo->getVc()); $cmd->setSubCommand('show'); - return //$this->repo->getVc()->getCommand('show') - $cmd + return $cmd ->addArgument($this->repo->hash . ':' . $this->path) ->execute(); } @@ -75,59 +84,63 @@ class File public function getRenderedContent(Tool_Result $res = null) { - $ext = $this->getExt(); - $class = '\\phorkie\\Renderer_Unknown'; - - if (isset($GLOBALS['phorkie']['languages'][$ext]['renderer'])) { - $class = $GLOBALS['phorkie']['languages'][$ext]['renderer']; - } else if ($this->isText()) { - $class = '\\phorkie\\Renderer_Geshi'; - } else if (isset($GLOBALS['phorkie']['languages'][$ext]['mime'])) { - $type = $GLOBALS['phorkie']['languages'][$ext]['mime']; - if (substr($type, 0, 6) == 'image/') { - $class = '\\phorkie\\Renderer_Image'; - } - } - - $rend = new $class(); - return $rend->toHtml($this, $res); + $cache = new Renderer_Cache(); + return $cache->toHtml($this, $res); } /** * Get a link to the file * - * @param string $type Link type. Supported are: - * - "raw" - * - "tool" - * @param string $option + * @param string $type Link type. Supported are: + * - "display" + * - "raw" + * - "tool" + * @param string $option Additional option, e.g. tool name + * @param boolean $full Return full URL or normal relative * * @return string */ - public function getLink($type, $option = null) + public function getLink($type, $option = null, $full = false) { if ($type == 'raw') { if ($this->repo->hash === null) { - return '/' . $this->repo->id . '/raw/' . $this->getFilename(); + $link = $this->repo->id . '/raw/' . $this->getFilename(); } else { - return '/' . $this->repo->id . '/rev-raw/' . $this->repo->hash + $link = $this->repo->id . '/rev-raw/' . $this->repo->hash . '/' . $this->getFilename(); } } else if ($type == 'tool') { - return '/' . $this->repo->id . '/tool/' . $option . '/' . $this->getFilename(); + $link = $this->repo->id + . '/tool/' . $option + . '/' . $this->getFilename(); + } else if ($type == 'display') { + $link = $this->repo->id . '#' . $this->getFilename(); + } else { + throw new Exception('Unknown type'); + } + + if ($full) { + $link = Tools::fullUrl($link); } - throw new Exception('Unknown type'); + return $link; } /** - * @return string Mime type of file + * @return string Mime type of file, NULL if no type detected */ public function getMimeType() { $ext = $this->getExt(); - if (!isset($GLOBALS['phorkie']['languages'][$ext])) { - return null; + if (isset($GLOBALS['phorkie']['languages'][$ext])) { + return $GLOBALS['phorkie']['languages'][$ext]['mime']; } - return $GLOBALS['phorkie']['languages'][$ext]['mime']; + + $mte = new \MIME_Type_Extension(); + $type = $mte->getMIMEType($this->getFilename()); + if (!\PEAR::isError($type)) { + return $type; + } + return null; } /** @@ -152,19 +165,55 @@ class File { $ext = $this->getExt(); if ($ext == '') { - //no file extension? then consider the size - $size = filesize($this->getFullPath()); - //files <= 4kiB are considered to be text - return $size <= 4096; + return $this->isNonBinary(); + } + + $type = $this->getMimeType(); + if ($type === null) { + return $this->isNonBinary(); } + return substr($type, 0, 5) === 'text/' + || $type == 'application/javascript' + || substr($type, -4) == '+xml' + || substr($type, -5) == '+json'; + } - if (!isset($GLOBALS['phorkie']['languages'][$ext]['mime'])) { + /** + * Look at the file's bytes and guess if it's binary or not. + * + * @return boolean True if it's most likely plain text + */ + public function isNonBinary() + { + $fp = fopen($this->getFullPath(), 'r'); + if (!$fp) { return false; } - $type = $GLOBALS['phorkie']['languages'][$ext]['mime']; - return substr($type, 0, 5) === 'text/' - || $type == 'application/javascript'; + //When multibyte extension is not installed, + // we only allow files with ASCII characters. + // Files with UTF-8 characters will not be detected as text. + $hasMb = function_exists('mb_detect_encoding'); + + $pos = 0; + $data = ''; + while (false !== ($char = fgetc($fp)) && ++$pos < 100) { + $data .= $char; + if (!$hasMb && ord($char) > 128) { + fclose($fp); + return false; + } + } + fclose($fp); + + if (!$hasMb) { + return true; + } + + if (mb_detect_encoding($data) === false) { + return false; + } + return true; } }