|
<?php |
|
|
|
/** |
|
* Elefant CMS Subfolder Proxy - http://www.elefantcms.com/ |
|
* |
|
* Copyright (c) 2012 Johnny Broadway |
|
* |
|
* Permission is hereby granted, free of charge, to any person obtaining a copy |
|
* of this software and associated documentation files (the "Software"), to deal |
|
* in the Software without restriction, including without limitation the rights |
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
|
* copies of the Software, and to permit persons to whom the Software is |
|
* furnished to do so, subject to the following conditions: |
|
* |
|
* The above copyright notice and this permission notice shall be included in |
|
* all copies or substantial portions of the Software. |
|
* |
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
|
* THE SOFTWARE. |
|
*/ |
|
|
|
|
|
/** |
|
* This is a proxy script that will enable Elefant to run inside of a |
|
* subfolder, which the main front controller does not support to keep |
|
* it nice and lightweight and to eliminate the need for extensive |
|
* repetition of a {{prefix}} type template variable. |
|
* |
|
* ## Caveat |
|
* |
|
* This is a workaround, and has certain drawbacks, but it does work. |
|
* It is of course better, whenever possible, to run Elefant in the |
|
* document root directly. The drawbacks are that this script adds |
|
* extra overhead not just to PHP scripts but also in proxying CSS |
|
* and JavaScript files too. Note that it doesn't affect other types |
|
* of files, or files outside of the subfolder in question. |
|
* |
|
* ## Usage |
|
* |
|
* To enable the subfolder proxy, here are the steps you need to take: |
|
* |
|
* 1. Replace the .htaccess file with the following: |
|
* |
|
|
|
<IfModule mod_rewrite.c> |
|
Options -MultiViews |
|
|
|
RewriteEngine On |
|
RewriteCond %{REQUEST_FILENAME} !-f [OR] |
|
RewriteCond %{REQUEST_FILENAME} \.(js|css)$ |
|
RewriteCond %{REQUEST_FILENAME} !-d |
|
RewriteRule . subfolder.php [L] |
|
</IfModule> |
|
|
|
DirectoryIndex subfolder.php |
|
|
|
* |
|
* 2. Drop this file (`subfolder.php`) beside your `index.php` file. |
|
* |
|
* 3. Proceed with the steps from the command line install method. |
|
* |
|
* You should now be able to run Elefant inside of any subfolder of your |
|
* choice. |
|
*/ |
|
|
|
|
|
/** |
|
* Determine the subfolder path, and alter the REQUEST_URI to trick |
|
* the front controller into thinking it's working at the document |
|
* root. |
|
*/ |
|
$cwd = str_replace ('\\', '/', getcwd ()); |
|
$root = rtrim ($_SERVER['DOCUMENT_ROOT'], '/'); |
|
define ('SUB_FOLDER', str_replace ($root, '', $cwd)); |
|
$_SERVER['REQUEST_URI'] = preg_replace ('|' . SUB_FOLDER . '|', '', $_SERVER['REQUEST_URI'], 1); |
|
|
|
|
|
/** |
|
* Pass the request on to the front controller if we're not inside of a |
|
* sub-folder. |
|
*/ |
|
if ($_SERVER['DOCUMENT_ROOT'] === getcwd ()) { |
|
require_once ('index.php'); |
|
return; |
|
} |
|
|
|
|
|
/** |
|
* Rewrite absolute references in JavaScript and CSS as well as PHP output. |
|
* |
|
* In JavaScript, we look for anything opening with a quote (single or double) |
|
* followed by a `/` and at least two alphanumeric characters. |
|
* |
|
* In CSS, we only have to look for `url(` references, which makes it a bit |
|
* simpler. |
|
*/ |
|
$path = parse_url ($_SERVER['REQUEST_URI'], PHP_URL_PATH); |
|
if (preg_match ('/\.(js|css)$/', $path, $matches)) { |
|
$file = preg_replace ('/^\//', '', $_SERVER['REQUEST_URI']); |
|
if ($matches[1] === 'js') { |
|
header ('Content-Type: application/javascript'); |
|
$out = preg_replace ('/(\'|")\/([a-zA-Z0-9_-]{2,}|\1)/', '\1' . SUB_FOLDER . '/\2', file_get_contents ($file)); |
|
$out = str_replace (SUB_FOLDER . SUB_FOLDER, SUB_FOLDER, $out); |
|
} else { |
|
header ('Content-Type: text/css'); |
|
$out = preg_replace ('/url\(([\'"]?)\//', 'url(\1' . SUB_FOLDER . '/', file_get_contents ($file)); |
|
$out = str_replace (SUB_FOLDER . SUB_FOLDER, SUB_FOLDER, $out); |
|
} |
|
header ('Cache-Control: max-age=604800, must-revalidate'); // 1 week |
|
header ('Content-Length: ' . strlen ($out)); |
|
echo $out; |
|
return; |
|
} |
|
|
|
|
|
/** |
|
* Define an exception we can throw to capture faked exit calls |
|
* (via `$controller->quit()`). |
|
*/ |
|
class SubfolderException extends Exception {} |
|
|
|
|
|
/** |
|
* Run the front controller and capture the headers and output. |
|
*/ |
|
ob_start (); |
|
try { |
|
require_once ('index.php'); |
|
} catch (SubfolderException $e) { |
|
/** |
|
* Catch calls to $controller->quit() and continue. |
|
*/ |
|
} |
|
$headers = headers_list (); |
|
$out = ob_get_clean (); |
|
|
|
|
|
/** |
|
* Alter any headers and re-send them. If the output is empty, we can |
|
* skip the output stage. |
|
*/ |
|
foreach ($headers as $header) { |
|
header ( |
|
preg_replace ( |
|
'/:\/\/' . preg_quote ($_SERVER['HTTP_HOST']) . '\//', |
|
'://' . $_SERVER['HTTP_HOST'] . rtrim (SUB_FOLDER, '/') . '/', |
|
$header |
|
) |
|
); |
|
} |
|
if (empty ($out)) { |
|
return; |
|
} |
|
|
|
|
|
/** |
|
* Reinstate the gzip output compression if it's enabled in the config |
|
* then send the altered output. |
|
*/ |
|
if (! defined ('ELEFANT_ENV')) { |
|
define ('ELEFANT_ENV', getenv ('ELEFANT_ENV') ? getenv ('ELEFANT_ENV') : 'config'); |
|
} |
|
$conf = parse_ini_file ('conf/' . ELEFANT_ENV . '.php', true); |
|
|
|
if ($conf['General']['compress_output'] && extension_loaded ('zlib')) { |
|
ob_start ('ob_gzhandler'); |
|
} |
|
|
|
if (strpos ($out, '\/') !== false) { |
|
$out = preg_replace ('/(\'|")\\\\\/([a-zA-Z0-9_-]{2,}|\1)/', '\1' . str_replace ('/', '\\/', SUB_FOLDER) . '\\/\2', $out); |
|
$out = str_replace ('\\' . SUB_FOLDER . '\\' . SUB_FOLDER, '\\' . SUB_FOLDER, $out); |
|
} |
|
$out = preg_replace ('/(\'|")\/([a-zA-Z0-9_-]{2,}|\1)/', '\1' . SUB_FOLDER . '/\2', $out); |
|
$out = str_replace (SUB_FOLDER . SUB_FOLDER, SUB_FOLDER, $out); |
|
echo $out; |
|
|
|
?> |