4 * Generates the appropriate mod_rewrite rules in the htaccess file.
5 * @note If a .htaccess.in prototype file is present in the directory,
6 * it will be used as the "base" htaccess to determine the new
7 * one, and local changes to .htaccess will ALWAYS be overwritten
12 $xc = XHTMLCompiler
::getInstance();
14 $identifier_begin = '# BEGIN xhtml-compiler/main.php mod_rewrite';
15 $identifier_end = '# END xhtml-compiler/main.php mod_rewrite';
16 $identifier_here = '# HERE xhtml-compiler/main.php mod_rewrite';
18 if (file_exists('.htaccess')) {
21 $files_to_check = array(
23 'xhtml-compiler/config.php',
24 'xhtml-compiler/config.default.php',
25 'xhtml-compiler/config.smoketest.php',
26 'xhtml-compiler/htaccess.php',
29 $mtime_htaccess = filemtime('.htaccess');
31 $no_changes_needed = true;
32 foreach ($files_to_check as $file) {
33 if (file_exists($file) && filemtime($file) > $mtime_htaccess) {
34 $no_changes_needed = false;
39 if ($no_changes_needed) {
40 throw new XHTMLCompiler_Exception(503, false,
41 'No changes detected in <tt>xhtml-compiler/config.php</tt>,
42 <tt>xhtml-compiler/config.default.php</tt> or
43 <tt>xhtml-compiler/htaccess.php</tt>.');
46 if (!file_exists('.htaccess.in')) {
47 $contents = file_get_contents('.htaccess');
49 $contents = file_get_contents('.htaccess.in');
52 // do writeability check
55 strpos($contents, $identifier_begin) === false ||
56 strpos($contents, $identifier_end) === false
58 strpos($contents, $identifier_here) === false
60 throw new XHTMLCompiler_Exception(503, false,
61 'Pre-existing htaccess not configured to accept new rules');
64 // replace old rules with new set
67 preg_quote($identifier_begin, '/') .
69 preg_quote($identifier_end, '/') .
72 $contents = preg_replace($regex, $identifier_here, $contents);
75 $contents = $identifier_here;
78 // build the new htaccess
79 $new_contents = array();
80 $new_contents[] = $identifier_begin;
81 $new_contents[] = 'RewriteEngine on';
84 $directory_index = $xc->getConf('directory_index');
85 $indexed_dirs = $xc->getConf('indexed_dirs');
86 $allowed_dirs = $xc->getConf('allowed_dirs');
87 foreach ($allowed_dirs as $dir => $recursive) {
90 $r = "([^/]+/)*"; // escaped slashes not necessary
93 $slash = (!$len ||
$dir[$len-1] === '/') ?
'' : '/';
94 $dir_exp = preg_quote($dir) . $slash . $r;
96 if (is_array($indexed_dirs)) {
97 $intercept = isset($indexed_dirs[$dir]) ?
$indexed_dirs[$dir] : true;
99 $intercept = $indexed_dirs;
101 if (is_string($directory_index) && $intercept) {
102 // setup index rewrite
103 $new_contents[] = "RewriteRule ^($dir_exp)$ \$1$directory_index";
105 $big_exp[] = $dir_exp;
108 $full_dir_exp = implode('|', $big_exp);
109 $new_contents[] = 'RewriteCond %{REQUEST_FILENAME} !-f [OR]';
110 $new_contents[] = 'RewriteCond %{QUERY_STRING} purge=1 [OR]';
111 $new_contents[] = 'RewriteCond %{HTTP_COOKIE} purgatory=1';
112 $new_contents[] = "RewriteRule ^(($full_dir_exp)[^/]+\.html)$ xhtml-compiler/main.php?f=\$1 [L,QSA]";
114 // if purge is set, also handle directories
115 $new_contents[] = 'RewriteCond %{QUERY_STRING} purge=1';
116 $new_contents[] = "RewriteRule ^($full_dir_exp)$ xhtml-compiler/main.php?f=\$1 [L,QSA]";
118 // xc-deps are forbidden to outside world
119 $new_contents[] = '<Files ~ "\.xc-deps$">';
120 $new_contents[] = ' Order allow,deny';
121 $new_contents[] = ' Deny from all';
122 $new_contents[] = '</Files>';
125 $new_contents[] = 'AddType application/rss+xml rss';
126 $new_contents[] = 'AddCharset UTF-8 .rss';
127 $new_contents[] = '<IfModule mod_headers.c>';
128 $new_contents[] = ' <Files ~ "\.rss$">';
129 $new_contents[] = ' Header append Cache-Control "no-cache, must-revalidate"';
130 $new_contents[] = ' </Files>';
131 $new_contents[] = '</IfModule>';
133 // set UTF-8 for HTML pages
134 $new_contents[] = 'AddCharset UTF-8 .html';
136 $new_contents[] = $identifier_end;
138 $contents = str_replace($identifier_here, implode($new_contents, PHP_EOL
), $contents);
140 file_put_contents('.htaccess', $contents);
141 chmod('.htaccess', 0644);
143 ?
><h1
>200: Okay
</h1
>New <tt
>.htaccess
</tt
> file successfully written