Allow usage in a subdir of a host.
[phorkie.git] / src / phorkie / File.php
1 <?php
2 namespace phorkie;
3
4 class File
5 {
6     /**
7      * Path to the file, relative to repository work directory
8      *
9      * @var string
10      */
11     public $path;
12
13     /**
14      * Repository this file belongs to
15      *
16      * @var string
17      */
18     public $repo;
19
20     /**
21      * Commit revision this file is at
22      */
23     public $hash;
24
25     public function __construct($path, Repository $repo = null)
26     {
27         $this->path = $path;
28         $this->repo = $repo;
29     }
30
31     /**
32      * Get filename relative to the repository path
33      *
34      * @return string
35      */
36     public function getFilename()
37     {
38         return $this->path;
39     }
40
41     /**
42      * Return the full path to the file
43      *
44      * @return string
45      */
46     public function getFullPath()
47     {
48         return $this->repo->workDir . '/' . $this->path;
49     }
50
51     /**
52      * Get file extension without dot
53      *
54      * @return string
55      */
56     public function getExt()
57     {
58         return substr($this->path, strrpos($this->path, '.') + 1);
59     }
60
61     public function getContent()
62     {
63         if ($this->repo->hash) {
64             //quick hack until https://pear.php.net/bugs/bug.php?id=19385 is fixed
65             $cmd = new GitCommandBinary($this->repo->getVc());
66             $cmd->setSubCommand('show');
67             return $cmd
68                 ->addArgument($this->repo->hash . ':' . $this->path)
69                 ->execute();
70         }
71
72         return file_get_contents($this->getFullPath());
73     }
74
75     public function getRenderedContent(Tool_Result $res = null)
76     {
77         $ext   = $this->getExt();
78         $class = '\\phorkie\\Renderer_Unknown';
79
80         if (isset($GLOBALS['phorkie']['languages'][$ext]['renderer'])) {
81             $class = $GLOBALS['phorkie']['languages'][$ext]['renderer'];
82         } else if ($this->isText()) {
83             $class = '\\phorkie\\Renderer_Geshi';
84         } else if (isset($GLOBALS['phorkie']['languages'][$ext]['mime'])) {
85             $type = $GLOBALS['phorkie']['languages'][$ext]['mime'];
86             if (substr($type, 0, 6) == 'image/') {
87                 $class = '\\phorkie\\Renderer_Image';
88             }
89         }
90
91         $rend = new $class();
92         return $rend->toHtml($this, $res);
93     }
94
95     /**
96      * Get a link to the file
97      *
98      * @param string $type   Link type. Supported are:
99      *                       - "raw"
100      *                       - "tool"
101      * @param string $option Additional option, e.g. tool name
102      *
103      * @return string
104      */
105     public function getLink($type, $option = null)
106     {
107         if ($type == 'raw') {
108             if ($this->repo->hash === null) {
109                 return $this->repo->id . '/raw/' . $this->getFilename();
110             } else {
111                 return $this->repo->id . '/rev-raw/' . $this->repo->hash
112                     . '/' . $this->getFilename();
113             }
114         } else if ($type == 'tool') {
115             return $this->repo->id
116                 . '/tool/' . $option
117                 . '/' . $this->getFilename();
118         }
119         throw new Exception('Unknown type');
120     }
121
122     /**
123      * @return string Mime type of file
124      */
125     public function getMimeType()
126     {
127         $ext = $this->getExt();
128         if (!isset($GLOBALS['phorkie']['languages'][$ext])) {
129             return null;
130         }
131         return $GLOBALS['phorkie']['languages'][$ext]['mime'];
132     }
133
134     /**
135      * @return array Array of Tool_Info objects
136      */
137     public function getToolInfos()
138     {
139         if ($this->repo->hash !== null) {
140             return array();
141         }
142
143         $tm = new Tool_Manager();
144         return $tm->getSuitable($this);
145     }
146
147     /**
148      * Tells if the file contains textual content and is editable.
149      *
150      * @return boolean
151      */
152     public function isText()
153     {
154         $ext = $this->getExt();
155         if ($ext == '') {
156             //no file extension? then consider the size
157             $size = filesize($this->getFullPath());
158             //files <= 4kiB are considered to be text
159             return $size <= 4096;
160         }
161
162         if (!isset($GLOBALS['phorkie']['languages'][$ext]['mime'])) {
163             return false;
164         }
165
166         $type = $GLOBALS['phorkie']['languages'][$ext]['mime'];
167         return substr($type, 0, 5) === 'text/'
168             || $type == 'application/javascript';
169     }
170 }
171
172 ?>