class File
{
/**
- * Full path to the file
+ * Path to the file, relative to repository work directory
*
* @var string
*/
*/
public $repo;
+ /**
+ * Commit revision this file is at
+ */
+ public $hash;
+
public function __construct($path, Repository $repo = null)
{
$this->path = $path;
*/
public function getFilename()
{
- return basename($this->path);
+ return $this->path;
+ }
+
+ /**
+ * Get the filename usable as HTML anchor.
+ *
+ * @return string
+ */
+ function getAnchorName()
+ {
+ return str_replace(' ', '-', $this->getFilename());
}
/**
*
* @return string
*/
- public function getPath()
+ public function getFullPath()
{
- return $this->path;
+ return $this->repo->workDir . '/' . $this->path;
}
/**
*/
public function getExt()
{
- return substr($this->path, strrpos($this->path, '.') + 1);
+ return strtolower(substr($this->path, strrpos($this->path, '.') + 1));
}
public function getContent()
{
- return file_get_contents($this->path);
+ if ($this->repo->hash) {
+ //quick hack until https://pear.php.net/bugs/bug.php?id=19385 is fixed
+ $cmd = new GitCommandBinary($this->repo->getVc());
+ $cmd->setSubCommand('show');
+ return $cmd
+ ->addArgument($this->repo->hash . ':' . $this->path)
+ ->execute();
+ }
+
+ return file_get_contents($this->getFullPath());
}
- public function getHighlightedContent(Tool_Result $res = null)
+ public function getRenderedContent(Tool_Result $res = null)
{
- $ext = $this->getExt();
- if (isset($GLOBALS['phorkie']['languages'][$ext]['renderer'])) {
- $class = $GLOBALS['phorkie']['languages'][$ext]['renderer'];
- } else {
- $class = '\\phorkie\\Renderer_Geshi';
- }
- $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') {
- return '/' . $this->repo->id . '/raw/' . $this->getFilename();
+ if ($this->repo->hash === null) {
+ $link = $this->repo->id . '/raw/' . $this->getFilename();
+ } else {
+ $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, 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;
}
/**
*/
public function getToolInfos()
{
+ if ($this->repo->hash !== null) {
+ return array();
+ }
+
$tm = new Tool_Manager();
return $tm->getSuitable($this);
}
+
+ /**
+ * Tells if the file contains textual content and is editable.
+ *
+ * @return boolean
+ */
+ public function isText()
+ {
+ $ext = $this->getExt();
+ if ($ext == '') {
+ 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';
+ }
+
+ /**
+ * 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;
+ }
+
+ //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;
+ }
}
-?>
\ No newline at end of file
+?>