2afda4c89fc8b2514ebef68a41d5ba3e1bc499aa
[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      * Get the filename usable as HTML anchor.
43      *
44      * @return string
45      */
46     function getAnchorName()
47     {
48         return str_replace(' ', '-', $this->getFilename());
49     }
50
51     /**
52      * Return the full path to the file
53      *
54      * @return string
55      */
56     public function getFullPath()
57     {
58         return $this->repo->workDir . '/' . $this->path;
59     }
60
61     /**
62      * Get file extension without dot
63      *
64      * @return string
65      */
66     public function getExt()
67     {
68         return strtolower(substr($this->path, strrpos($this->path, '.') + 1));
69     }
70
71     public function getContent()
72     {
73         if ($this->repo->hash) {
74             //quick hack until https://pear.php.net/bugs/bug.php?id=19385 is fixed
75             $cmd = new GitCommandBinary($this->repo->getVc());
76             $cmd->setSubCommand('show');
77             return $cmd
78                 ->addArgument($this->repo->hash . ':' . $this->path)
79                 ->execute();
80         }
81
82         return file_get_contents($this->getFullPath());
83     }
84
85     public function getRenderedContent(Tool_Result $res = null)
86     {
87         $ext   = $this->getExt();
88         $class = '\\phorkie\\Renderer_Unknown';
89
90         if (isset($GLOBALS['phorkie']['languages'][$ext]['renderer'])) {
91             $class = $GLOBALS['phorkie']['languages'][$ext]['renderer'];
92         } else if ($this->isText()) {
93             $class = '\\phorkie\\Renderer_Geshi';
94         } else if (isset($GLOBALS['phorkie']['languages'][$ext]['mime'])) {
95             $type = $GLOBALS['phorkie']['languages'][$ext]['mime'];
96             if (substr($type, 0, 6) == 'image/') {
97                 $class = '\\phorkie\\Renderer_Image';
98             }
99         }
100
101         $rend = new $class();
102         return $rend->toHtml($this, $res);
103     }
104
105     /**
106      * Get a link to the file
107      *
108      * @param string $type   Link type. Supported are:
109      *                       - "display"
110      *                       - "raw"
111      *                       - "tool"
112      * @param string $option Additional option, e.g. tool name
113      * @param boolean $full   Return full URL or normal relative
114      *
115      * @return string
116      */
117     public function getLink($type, $option = null, $full = false)
118     {
119         if ($type == 'raw') {
120             if ($this->repo->hash === null) {
121                 $link = $this->repo->id . '/raw/' . $this->getFilename();
122             } else {
123                 $link = $this->repo->id . '/rev-raw/' . $this->repo->hash
124                     . '/' . $this->getFilename();
125             }
126         } else if ($type == 'tool') {
127             $link = $this->repo->id
128                 . '/tool/' . $option
129                 . '/' . $this->getFilename();
130         } else if ($type == 'display') {
131             $link = $this->repo->id . '#' . $this->getFilename();
132         } else {
133             throw new Exception('Unknown type');
134         }
135
136         if ($full) {
137             $link = Tools::fullUrl($link);
138         }
139         return $link;
140     }
141
142     /**
143      * @return string Mime type of file
144      */
145     public function getMimeType()
146     {
147         $ext = $this->getExt();
148         if (!isset($GLOBALS['phorkie']['languages'][$ext])) {
149             return null;
150         }
151         return $GLOBALS['phorkie']['languages'][$ext]['mime'];
152     }
153
154     /**
155      * @return array Array of Tool_Info objects
156      */
157     public function getToolInfos()
158     {
159         if ($this->repo->hash !== null) {
160             return array();
161         }
162
163         $tm = new Tool_Manager();
164         return $tm->getSuitable($this);
165     }
166
167     /**
168      * Tells if the file contains textual content and is editable.
169      *
170      * @return boolean
171      */
172     public function isText()
173     {
174         $ext = $this->getExt();
175         if ($ext == '') {
176             //no file extension? then consider the size
177             $size = filesize($this->getFullPath());
178             //files <= 4kiB are considered to be text
179             return $size <= 4096;
180         }
181
182         if (!isset($GLOBALS['phorkie']['languages'][$ext]['mime'])) {
183             return false;
184         }
185
186         $type = $GLOBALS['phorkie']['languages'][$ext]['mime'];
187         return substr($type, 0, 5) === 'text/'
188             || $type == 'application/javascript'
189             || substr($type, -4) == '+xml'
190             || substr($type, -5) == '+json';
191     }
192 }
193
194 ?>