javascript embedding support
[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 strtolower(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      *                       - "display"
100      *                       - "raw"
101      *                       - "tool"
102      * @param string $option Additional option, e.g. tool name
103      * @param boolean $full   Return full URL or normal relative
104      *
105      * @return string
106      */
107     public function getLink($type, $option = null, $full = false)
108     {
109         if ($type == 'raw') {
110             if ($this->repo->hash === null) {
111                 $link = $this->repo->id . '/raw/' . $this->getFilename();
112             } else {
113                 $link = $this->repo->id . '/rev-raw/' . $this->repo->hash
114                     . '/' . $this->getFilename();
115             }
116         } else if ($type == 'tool') {
117             $link = $this->repo->id
118                 . '/tool/' . $option
119                 . '/' . $this->getFilename();
120         } else if ($type == 'display') {
121             $link = $this->repo->id . '#' . $this->getFilename();
122         } else {
123             throw new Exception('Unknown type');
124         }
125
126         if ($full) {
127             $link = Tools::fullUrl($link);
128         }
129         return $link;
130     }
131
132     /**
133      * @return string Mime type of file
134      */
135     public function getMimeType()
136     {
137         $ext = $this->getExt();
138         if (!isset($GLOBALS['phorkie']['languages'][$ext])) {
139             return null;
140         }
141         return $GLOBALS['phorkie']['languages'][$ext]['mime'];
142     }
143
144     /**
145      * @return array Array of Tool_Info objects
146      */
147     public function getToolInfos()
148     {
149         if ($this->repo->hash !== null) {
150             return array();
151         }
152
153         $tm = new Tool_Manager();
154         return $tm->getSuitable($this);
155     }
156
157     /**
158      * Tells if the file contains textual content and is editable.
159      *
160      * @return boolean
161      */
162     public function isText()
163     {
164         $ext = $this->getExt();
165         if ($ext == '') {
166             //no file extension? then consider the size
167             $size = filesize($this->getFullPath());
168             //files <= 4kiB are considered to be text
169             return $size <= 4096;
170         }
171
172         if (!isset($GLOBALS['phorkie']['languages'][$ext]['mime'])) {
173             return false;
174         }
175
176         $type = $GLOBALS['phorkie']['languages'][$ext]['mime'];
177         return substr($type, 0, 5) === 'text/'
178             || $type == 'application/javascript'
179             || substr($type, -4) == '+xml'
180             || substr($type, -5) == '+json';
181     }
182 }
183
184 ?>