Prefer extensionless URLs.
[xhtml-compiler.git] / functions.php
blob11f1b985244fe3e4a1c2d7e360fa1c94dd010bef
1 <?php
3 /**
4 * Returns true if in cli mode
5 */
6 function is_cli() {
7 return php_sapi_name() === 'cli';
10 /**
11 * Convenience function that outputs an HTTP status code
12 * @param $code integer HTTP status code
13 * @return string HTTP status code's name
15 function set_response_code($code) {
16 $php = XHTMLCompiler::getPHPWrapper();
17 $code_descriptions = array( // could be factored out
18 200 => 'Okay',
19 304 => 'Not Modified',
20 401 => 'Unauthorized',
21 403 => 'Forbidden',
22 404 => 'Not Found',
23 500 => 'Internal Server Error',
24 503 => 'Service Unavailable',
26 $code = (int) $code; // enforce integer
27 $text = (string) $code;
28 if (isset($code_descriptions[$code])) {
29 $text .= ' ' . $code_descriptions[$code];
31 if (isset($_SERVER['SERVER_PROTOCOL'])) {
32 $php->header($_SERVER['SERVER_PROTOCOL'] . ' ' . $text, true, $code);
33 $php->header('Status: ' . $text);
35 return $text;
38 /**
39 * Determines the requested page from server environment files
40 * @return string page name
42 function get_page_from_server() {
43 $php = XHTMLCompiler::getPHPWrapper();
44 // load up page from environment variables, if using ErrorDocument impl.
45 $page = $php->getRequestURI();
46 $self = dirname($php->getPHPSelf());
47 $root = strlen(substr($self, 0, strrpos($self, '/')));
48 $page = substr($page, $root + 1); // remove leading slash and root
49 return $page;
52 /**
53 * Determines the requested page from get parameter
54 * @return string page name
56 function get_page_from_get() {
57 $php = XHTMLCompiler::getPHPWrapper();
58 return $php->getGVal('f');
61 /**
62 * Takes a page name and appends index filename if necessary
63 * @param $page string page name
64 * @param $directory_index string name of file to use as directory index
66 function normalize_index($page, $directory_index) {
67 $php = XHTMLCompiler::getPHPWrapper();
68 if ($page == '') $page = $directory_index;
69 if ($php->isDir($page)) {
70 if ($page[strlen($page)-1] !== '/') $page .= '/';
71 $page .= $directory_index;
73 return $page;
76 /**
77 * Determines whether or not an .html file was generated by us
78 * @param $page filename of page, must exist
80 function is_created_by_us($page) {
81 $contents = file_get_contents($page);
82 return (strpos($contents, '<!-- generated by XHTML Compiler -->') !== false);
85 /**
86 * Exception handler, prints a pretty HTTP error message
87 * @param $e The uncaught exception
88 * @todo Augment debug mode to have stack traces
89 * @todo Make more friendly to command-line
91 function xhtmlcompiler_exception_handler(Exception $e) {
92 $xc = XHTMLCompiler::getInstance();
93 $php = XHTMLCompiler::getPHPWrapper();
95 if (is_cli()) {
96 $php->paint((string) $e);
97 return;
100 $error_xsl = $xc->getConf('error_xsl');
102 // extract information out of exception
103 if ($e instanceof XHTMLCompiler_Exception) {
104 $code = $e->getCode();
105 $title = $e->getMessage();
106 $details = $e->getDetails();
107 } else {
108 $code = 500;
109 $title = false;
110 $details = $e->getMessage();
113 // send appropriate response code
114 $default = set_response_code($code);
116 // munge the title
117 if (!$title) $title = $default;
118 else $title = $code . ' ' . $title;
120 // build a error document
121 $page = new DOMDocument('1.0', 'utf-8');
122 $error = $page->createElement('error'); $page->appendChild($error);
123 $error->appendChild($page->createElement('code', $code));
124 $error->appendChild($page->createElement('title', $title));
125 $error->appendChild($page->createElement('base', $xc->getConf('web_path')));
127 // details (in HTML)
128 if ($details) {
129 $html = $page->createDocumentFragment();
130 $html->appendXML($details);
131 $details_dom = $page->createElement('details');
132 $details_dom->appendChild($html);
133 $error->appendChild($details_dom);
136 // debug
137 if ($xc->getConf('debug')) {
138 $debug = $page->createElement('debug');
139 $debug->appendChild($page->createElement('base-dir', $base = dirname(__FILE__)));
140 $debug->appendChild($page->createElement('file', shortenFile($e->getFile(), $base)));
141 $debug->appendChild($page->createElement('line', $e->getLine()));
142 $error->appendChild($debug);
145 // generate and output html
146 $xslt_processor = new ConfigDoc_HTMLXSLTProcessor();
147 $xslt_processor->importStylesheet(dirname(__FILE__) . '/../' . $error_xsl);
148 $html = $xslt_processor->transformToHTML($page);
149 $php->paint($html);
154 /** Returns short filename based on a base directory */
155 function shortenFile($file, $base) {
156 if (strpos($file, $base) === 0) {
157 $file = str_replace('\\', '/', substr($file, strlen($base)));
158 if ($file === '') $file = '.';
159 if ($file[0] === '/') $file = substr($file, 1);
161 return $file;
165 * Checks for errors, and sends a notification email if necessary
167 function check_errors() {
168 $xc = XHTMLCompiler::getInstance();
169 $error_log = $xc->getConf('error_log');
170 $error_mute = $xc->getConf('error_mute');
171 if (file_exists($error_log) && filesize($error_log) > 0) {
172 if (file_exists($error_mute) && filesize($error_mute) == 0) {
173 $error_text = wordwrap(file_get_contents($error_log), 70, "\r\n");
174 try {
175 $message = Swift_Message::newInstance()
176 ->setSubject('Errors in XHTML Compiler')
177 ->setTo($xc->getConf('admin_email'))
178 ->setFrom($xc->getConf('from_email'))
179 ->setBody(<<<BODY
180 Some errors occured in the log. No further messages
181 will be sent until the mute file [1] is deleted. The
182 error log file [2] will be blanked after resolving any
183 issues.
185 [1] $error_mute
186 [2] $error_log
188 $error_text
189 BODY
191 $xc->getConf('smtp_transport')->send($message);
192 } catch (Exception $e) {
193 // uh oh, mail failed, not much we can do about that.
194 if ($xc->getConf('debug')) {
195 echo $e . "\n";
198 file_put_contents($error_mute, '1');
199 } elseif (!file_exists($error_mute) && file_exists($error_log)) {
200 $tentative_new_name = "$error_log." . date('Ymd');
201 $i = 0;
202 $new_name = $tentative_new_name;
203 while (file_exists($tentative_new_name) && file_exists($new_name)) {
204 $new_name = "$tentative_new_name-$i";
205 $i++;
207 copy($error_log, $new_name);
208 file_put_contents($error_log, '');
209 file_put_contents($error_mute, '');