4 * Convenience function that outputs an HTTP status code
5 * @param $code integer HTTP status code
6 * @return string HTTP status code's name
8 function set_response_code($code) {
9 $php = XHTMLCompiler
::getPHPWrapper();
10 $code_descriptions = array( // could be factored out
12 304 => 'Not Modified',
13 401 => 'Unauthorized',
16 500 => 'Internal Server Error',
17 503 => 'Service Unavailable',
19 $code = (int) $code; // enforce integer
20 $text = (string) $code;
21 if (isset($code_descriptions[$code])) {
22 $text .= ' ' . $code_descriptions[$code];
24 if (isset($_SERVER['SERVER_PROTOCOL'])) {
25 $php->header($_SERVER['SERVER_PROTOCOL'] . ' ' . $text, true, $code);
26 $php->header('Status: ' . $text);
32 * Determines the requested page from server environment files
33 * @return string page name
35 function get_page_from_server() {
36 $php = XHTMLCompiler
::getPHPWrapper();
37 // load up page from environment variables, if using ErrorDocument impl.
38 $page = $php->getRequestURI();
39 $self = dirname($php->getPHPSelf());
40 $root = strlen(substr($self, 0, strrpos($self, '/')));
41 $page = substr($page, $root +
1); // remove leading slash and root
46 * Determines the requested page from get parameter
47 * @return string page name
49 function get_page_from_get() {
50 $php = XHTMLCompiler
::getPHPWrapper();
51 return $php->getGVal('f');
55 * Takes a page name and appends index filename if necessary
56 * @param $page string page name
57 * @param $directory_index string name of file to use as directory index
59 function normalize_index($page, $directory_index) {
60 $php = XHTMLCompiler
::getPHPWrapper();
61 if ($page == '') $page = $directory_index;
62 if ($php->isDir($page)) {
63 if ($page[strlen($page)-1] !== '/') $page .= '/';
64 $page .= $directory_index;
70 * Determines whether or not an .html file was generated by us
71 * @param $page filename of page, must exist
73 function is_created_by_us($page) {
74 $contents = file_get_contents($page);
75 return (strpos($contents, '<!-- generated by XHTML Compiler -->') !== false);
79 * Exception handler, prints a pretty HTTP error message
80 * @param $e The uncaught exception
81 * @todo Augment debug mode to have stack traces
82 * @todo Make more friendly to command-line
84 function xhtmlcompiler_exception_handler(Exception
$e) {
85 $xc = XHTMLCompiler
::getInstance();
86 $php = XHTMLCompiler
::getPHPWrapper();
88 $error_xsl = $xc->getConf('error_xsl');
90 // extract information out of exception
91 if ($e instanceof XHTMLCompiler_Exception
) {
92 $code = $e->getCode();
93 $title = $e->getMessage();
94 $details = $e->getDetails();
98 $details = $e->getMessage();
101 // send appropriate response code
102 $default = set_response_code($code);
105 if (!$title) $title = $default;
106 else $title = $code . ' ' . $title;
108 // build a error document
109 $page = new DOMDocument('1.0', 'utf-8');
110 $error = $page->createElement('error'); $page->appendChild($error);
111 $error->appendChild($page->createElement('code', $code));
112 $error->appendChild($page->createElement('title', $title));
113 $error->appendChild($page->createElement('base', $xc->getConf('web_path')));
117 $html = $page->createDocumentFragment();
118 $html->appendXML($details);
119 $details_dom = $page->createElement('details');
120 $details_dom->appendChild($html);
121 $error->appendChild($details_dom);
125 if ($xc->getConf('debug')) {
126 $debug = $page->createElement('debug');
127 $debug->appendChild($page->createElement('base-dir', $base = dirname(__FILE__
)));
128 $debug->appendChild($page->createElement('file', shortenFile($e->getFile(), $base)));
129 $debug->appendChild($page->createElement('line', $e->getLine()));
130 $error->appendChild($debug);
133 // generate and output html
134 $xslt_processor = new ConfigDoc_HTMLXSLTProcessor();
135 $xslt_processor->importStylesheet(dirname(__FILE__
) . '/../' . $error_xsl);
136 $html = $xslt_processor->transformToHTML($page);
142 /** Returns short filename based on a base directory */
143 function shortenFile($file, $base) {
144 if (strpos($file, $base) === 0) {
145 $file = str_replace('\\', '/', substr($file, strlen($base)));
146 if ($file === '') $file = '.';
147 if ($file[0] === '/') $file = substr($file, 1);
153 * Retrieves the last $limit log entries.
154 * @param $repos_url Repository URL of item to get logs for
155 * @param $limit Integer limit of items
157 function svn_log_limit($repos_url, $limit, $page = null) {
158 $limit = (int) $limit;
159 if ($limit <= 0) return array();
161 $cache_filename = 'xhtml-compiler/cache/svn/log/' . md5($repos_url) . '.ser';
162 if ($page && file_exists($cache_filename)) {
163 $logs = unserialize(file_get_contents($cache_filename));
164 // determine current revision number
165 $rev = $page->getSVNRevision();
166 if ($logs[0]['rev'] == $rev) return $logs;
168 // -q flag used to prevent server from sending log messages
169 $output = shell_exec("svn log -q --limit $limit $repos_url");
170 preg_match_all('/^r(\d+) /m', $output, $matches);
172 foreach ($matches[1] as $rev) {
173 $log = svn_log($repos_url, (int) $rev);
174 $ret[] = $log[0]; // log is only one item long
177 file_put_contents($cache_filename, serialize($ret));