ConstruccionesCNJ_Web/Source/gallery2/modules/rewrite/classes/parsers/modrewrite/ModRewriteHelper.class

699 lines
21 KiB
Plaintext
Raw Permalink Normal View History

<?php
/*
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2007 Bharat Mediratta
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
/**
* Apache mod_rewrite helper.
* @package Rewrite
* @subpackage Parsers
* @author Douglas Cau <douglas@cau.se>
* @version $Revision: 15990 $
*/
class ModRewriteHelper {
/**
* @see RewriteParser::saveActiveRules
*/
function saveActiveRules($parser, $activeRules=null, $upgradeModule=null) {
list ($ret, $code) = ModRewriteHelper::checkFile();
if ($ret) {
return array($ret, null, null);
}
if ($code != REWRITE_STATUS_OK) {
return array(null, $code, null);
}
if (GalleryUtilities::isEmbedded()) {
list ($ret, $code) = ModRewriteHelper::checkFile(true);
if ($ret) {
return array($ret, null, null);
}
if ($code != REWRITE_STATUS_OK) {
return array(null, $code, null);
}
}
/* By default we use the rules we've already got */
if (is_null($activeRules)) {
list($ret, $activeRules) = GalleryCoreApi::getPluginParameter(
'module', 'rewrite', 'activeRules');
if ($ret) {
return array($ret, null, null);
}
$activeRules = unserialize($activeRules);
}
$regexRules = array();
$shortUrls = array();
$flags = array('default' => array('QSA', 'L'), 'mandatory' => array());
if (!empty($activeRules)) {
list ($ret, $code, $regexRules, $shortUrls, $errorId) =
RewriteHelper::parseActiveRules($activeRules, $parser, $upgradeModule, $flags);
if ($ret) {
return array($ret, null, null);
}
if ($code != REWRITE_STATUS_OK) {
return array(null, $code, $errorId);
}
}
/* Write the standalone .htaccess */
list ($ret, $code) = ModRewriteHelper::writeFile($regexRules);
if ($ret) {
return array($ret, null, null);
}
if ($code != REWRITE_STATUS_OK) {
return array(null, $code, null);
}
/* Write the embedded .htaccess */
if (GalleryUtilities::isEmbedded()) {
list ($ret, $code) = ModRewriteHelper::writeFile($regexRules, true);
if ($ret) {
return array($ret, null, null);
}
if ($code != REWRITE_STATUS_OK) {
return array(null, $code, null);
}
}
/* Finally, save the new rules */
$ret = GalleryCoreApi::setPluginParameter(
'module', 'rewrite', 'shortUrls', serialize($shortUrls));
if ($ret) {
return array($ret, null, null);
}
$ret = GalleryCoreApi::setPluginParameter(
'module', 'rewrite', 'activeRules', serialize($activeRules));
if ($ret) {
return array($ret, null, null);
}
return array(null, REWRITE_STATUS_OK, null);
}
/**
* @see RewriteParser::saveAccessList
*/
function saveAccessList($accessList, $allowEmptyReferer) {
list ($ret, $code) = ModRewriteHelper::checkFile();
if ($ret) {
return array($ret, null);
}
if ($code != REWRITE_STATUS_OK) {
return array(null, $code);
}
if (GalleryUtilities::isEmbedded()) {
list ($ret, $code) = ModRewriteHelper::checkFile(true);
if ($ret) {
return array($ret, null);
}
if ($code != REWRITE_STATUS_OK) {
return array(null, $code);
}
}
$ret = GalleryCoreApi::setPluginParameter(
'module', 'rewrite', 'accessList', serialize($accessList));
if ($ret) {
return array($ret, null);
}
$ret = GalleryCoreApi::setPluginParameter(
'module', 'rewrite', 'allowEmptyReferer', $allowEmptyReferer ? '1' : '0');
if ($ret) {
return array($ret, null);
}
/* Save the new .htaccess */
list ($ret, $code) = $this->saveActiveRules();
if ($ret) {
return array($ret, null);
}
return array(null, $code);
}
/**
* @see RewriteParser::needsConfiguration
*/
function needsConfiguration() {
global $gallery;
$urlGenerator =& $gallery->getUrlGenerator();
if (strpos($urlGenerator->getCurrentUrlDir(true), 'install/index.php') !== false &&
$gallery->getConfig('galleryBaseUrl')) {
/*
* We can't autoconfigure from installer in a multisite install because the current URL
* is for the primary site, not the site being installed.
*/
return array(null, true);
}
$baseUrlComponents = parse_url(preg_replace('{(install|upgrade)/index\.php.*}', '',
$urlGenerator->getCurrentUrlDir(true)));
$ret = GalleryCoreApi::setPluginParameter('module', 'rewrite',
'modrewrite.galleryLocation', $baseUrlComponents['path']);
if ($ret) {
return array($ret, null);
}
list ($ret, $code) = ModRewriteHelper::checkModRewrite();
if ($ret) {
return array($ret, null);
}
if ($code != REWRITE_STATUS_OK) {
return array(null, true);
}
list ($ret, $code) = ModRewriteHelper::checkFile();
if ($ret) {
return array($ret, null);
}
if ($code != REWRITE_STATUS_OK) {
return array(null, true);
}
if (GalleryUtilities::isEmbedded()) {
list ($ret, $code) = ModRewriteHelper::checkFile(true);
if ($ret) {
return array($ret, null);
}
if ($code != REWRITE_STATUS_OK) {
return array(null, true);
}
}
return array(null, false);
}
/**
* Return the .htaccess content given a set or rewrite rules.
* @param array $regexRules regular expression rules with settings
* @param boolean $embedded (optional) true if the embedded .htaccess is wanted
* @return array object GalleryStatus a status code
* string the Gallery .htaccess section
*/
function getHtaccessContent($regexRules, $embedded=false) {
global $gallery;
$urlGenerator =& $gallery->getUrlGenerator();
$Htaccess = array();
list ($ret, $Htaccess['galleryDirectory']) = GalleryCoreApi::getPluginParameter(
'module', 'rewrite', 'modrewrite.galleryLocation');
if ($ret) {
return array($ret, null);
}
list ($ret, $status) = GalleryCoreApi::getPluginParameter(
'module', 'rewrite', 'modrewrite.status');
if ($ret) {
return array($ret, null);
}
$status = unserialize($status);
$Htaccess['needOptions'] = $status['needOptions'];
$Htaccess['directory'] = $Htaccess['galleryDirectory'];
$Htaccess['rewriteBase'] = $Htaccess['galleryDirectory'];
$Htaccess['baseFile'] = GALLERY_MAIN_PHP;
if ($embedded) {
$Htaccess['baseFile'] = $urlGenerator->_file[false];
list ($ret, $Htaccess['directory']) = GalleryCoreApi::getPluginParameter(
'module', 'rewrite', 'modrewrite.embeddedLocation');
if ($ret) {
return array($ret, null);
}
$Htaccess['rewriteBase'] = $Htaccess['directory'];
$components = parse_url($Htaccess['baseFile']);
if (isset($components['host'])) {
$Htaccess['directory'] = '';
}
}
$Htaccess['matchBaseFile'] = $Htaccess['directory']
. preg_quote(preg_replace('/\?.*/', '', $Htaccess['baseFile']));
/* Substitute with what the Gallery URL generator would generate */
$galleryUrlGenerator = new GalleryUrlGenerator();
$galleryUrlGenerator->init($Htaccess['directory'] . $Htaccess['baseFile'],
$Htaccess['galleryDirectory'] . GALLERY_MAIN_PHP);
foreach ($regexRules as $ruleId => $regexRule) {
/* Conditions */
if (!empty($regexRule['conditions'])) {
foreach ($regexRule['conditions'] as $conditionId => $condition) {
/*
* Apache mod_rewrite supports only certain flags:
* http://httpd.apache.org/docs/2.2/mod/mod_rewrite.html#rewritecond
*/
if (!empty($condition['flags'])) {
$condition['flags'] = array_intersect($condition['flags'],
array('NC', 'OR'));
}
$regexRule['conditions'][$conditionId] = $condition;
}
}
/* Pattern */
if (!empty($regexRule['pattern'])) {
$regexRule['conditions'][] = array(
'test' => 'THE_REQUEST',
'pattern' => $Htaccess['rewriteBase'] . $regexRule['pattern'] . '(\\?.|\\ .)');
$regexRule['conditions'][] = array(
'test' => 'REQUEST_URI',
'pattern' => '!' . $Htaccess['matchBaseFile'] . '$');
}
/* Substitution */
$params = $regexRule['queryString'];
foreach ($regexRule['keywords'] as $reference => $name) {
if (empty($name)) {
continue;
}
/* $N are RewriteRule backreferences, %N are RewriteCond backreferences */
$params[$name] = '%' . $reference;
}
$regexRule['substitution'] = $galleryUrlGenerator->generateUrl(
$params, $regexRule['options']);
$regexRules[$ruleId] = $regexRule;
}
$Htaccess['rules'] = $regexRules;
/* Render template */
GalleryCoreApi::requireOnce('modules/core/classes/GalleryTemplate.class');
$template = new GalleryTemplate(dirname(__FILE__) . '/../../../templates', true, false);
$template->setVariable('Htaccess', $Htaccess);
$template->setVariable('l10Domain', 'modules_rewrite');
list ($ret, $content) = $template->fetch('Htaccess.tpl');
if ($ret) {
return array($ret, null);
}
return array(null, $content);
}
/**
* Return the absolute path to the .htaccess file.
* @param boolean $embedded (optional) true if embedded .htaccess is wanted
* @return array object GalleryStatus a status code
* string .htaccess file path
*/
function getHtaccessPath($embedded=false) {
if ($embedded) {
list ($ret, $path) = GalleryCoreApi::getPluginParameter(
'module', 'rewrite', 'modrewrite.embeddedHtaccess');
if ($ret) {
return array($ret, null);
}
return array(null, $path . '/.htaccess');
}
return array(null, GALLERY_CONFIG_DIR . '/.htaccess');
}
/**
* Check if the .htaccess file is writeable.
* @param boolean $embedded (optional) if true then the embedded .htaccess is checked
* @return array object GalleryStatus a status code
* int rewrite status code (REWRITE_STATUS_OK on success)
*/
function checkFile($embedded=false) {
global $gallery;
$platform =& $gallery->getPlatform();
list ($ret, $file) = ModRewriteHelper::getHtaccessPath($embedded);
if ($ret) {
return array($ret, null);
}
if ($platform->file_exists($file)) {
/* Can't read the .htaccess file */
if (!$platform->is_readable($file)) {
return array(null,
$embedded ? REWRITE_STATUS_EMBED_HTACCESS_CANT_READ
: REWRITE_STATUS_HTACCESS_CANT_READ);
}
/* Can't write the .htaccess file */
if (!$platform->is_writeable($file)) {
return array(null,
$embedded ? REWRITE_STATUS_EMBED_HTACCESS_CANT_WRITE
: REWRITE_STATUS_HTACCESS_CANT_WRITE);
}
} else {
/* If we have write access to the directory we can create the file */
if (!$platform->is_writeable(dirname($file))) {
return array(null,
$embedded ? REWRITE_STATUS_EMBED_HTACCESS_MISSING
: REWRITE_STATUS_HTACCESS_MISSING);
}
}
return array(null, REWRITE_STATUS_OK);
}
/**
* Write Gallery data to the .htaccess file.
* @param array $regexRules regular expression rules with settings
* @param boolean $embedded (optional) if true then the embedded .htaccess is written
* @return array object GalleryStatus a status code
* int rewrite status code
*/
function writeFile($regexRules, $embedded=false) {
global $gallery;
$platform =& $gallery->getPlatform();
list ($ret, $file) = ModRewriteHelper::getHtaccessPath($embedded);
if ($ret) {
return array($ret, null);
}
$htaccess = '#{gallerySection}';
if (!empty($regexRules)) {
list ($ret, $htaccess) = ModRewriteHelper::getHtaccessContent($regexRules, $embedded);
if ($ret) {
return array($ret, null);
}
}
if ($platform->file_exists($file)) {
if (!$platform->is_readable($file)) {
return array(null, $embedded ? REWRITE_STATUS_EMBED_HTACCESS_CANT_READ
: REWRITE_STATUS_HTACCESS_CANT_READ);
}
$oldHtaccess = implode('', $platform->file($file));
$newHtaccess = preg_replace(
'/\# BEGIN Url Rewrite section(.+)\# END Url Rewrite section(\r\n|\n|\r)/s',
'#{gallerySection}', $oldHtaccess);
if (strpos($newHtaccess, '#{gallerySection}') !== false) {
$newHtaccess = str_replace('#{gallerySection}', $htaccess, $newHtaccess);
} else {
$newHtaccess = $htaccess . "\n" . $oldHtaccess;
}
} else {
$newHtaccess = $htaccess;
}
/* Write the new file */
if ($fd = @$platform->fopen($file, 'w')) {
$platform->fwrite($fd, $newHtaccess);
$platform->fclose($fd);
} else {
return array(null, $embedded ? REWRITE_STATUS_EMBED_HTACCESS_CANT_WRITE
: REWRITE_STATUS_HTACCESS_CANT_WRITE);
}
return array(null, REWRITE_STATUS_OK);
}
/**
* Returns one of the following codes:
* REWRITE_STATUS_OK everything is fine
* REWRITE_STATUS_APACHE_NO_MOD_REWRITE no mod rewrite support
* REWRITE_STATUS_APACHE_UNABLE_TO_TEST unable to properly test mod_rewrite
* REWRITE_STATUS_MULTISITE can't test mod_rewrite in multisite
*
* @return array object GalleryStatus a status code
* int rewrite status code
* int rewrite true status code
*/
function checkModRewrite() {
global $gallery;
$urlGenerator =& $gallery->getUrlGenerator();
list ($ret, $status) = GalleryCoreApi::getPluginParameter('module', 'rewrite',
'modrewrite.status');
if ($ret) {
return array($ret, null, null);
}
$status = unserialize($status);
/* We can't test with multisite, there are no test files */
if ($gallery->getConfig('galleryBaseUrl')) {
return array(null, isset($status['forced']) ? REWRITE_STATUS_OK
: REWRITE_STATUS_MULTISITE,
REWRITE_STATUS_MULTISITE);
}
$baseUrl = preg_replace(
'{(install|upgrade)/index\.php.*}', '', $urlGenerator->getCurrentUrlDir(true));
$components = parse_url($baseUrl);
$path = $components['path'];
$baseUrl .= 'modules/rewrite/data/';
/*
* Testing mod_rewrite functionality. For mod_rewrite to work properly, it needs a
* .htaccess file containing a RewriteBase directive matching the URL of its containing
* directory.
*/
if ($path == '/gallery2/') {
$target = 'gallery2';
} else if ($path == '/gallery/') {
$target = 'gallery';
} else {
$target = 'custom';
}
$fetch = $baseUrl . "mod_rewrite_no_options/$target/Rewrite.txt";
list ($success, $body) = GalleryCoreAPI::fetchWebPage($fetch);
if ($success && !strncmp('PASS_REWRITE', $body, 12)) {
$ret = GalleryCoreApi::setPluginParameter('module', 'rewrite', 'modrewrite.status',
serialize(array('needOptions' => false)));
if ($ret) {
return array($ret, null, null);
}
return array(null, REWRITE_STATUS_OK, REWRITE_STATUS_OK);
}
/*
* mod_rewrite needs Options +FollowSymlinks and we might need to explicitly require it in
* the .htaccess file.
*/
$fetch = $baseUrl . "mod_rewrite/$target/Rewrite.txt";
list ($success, $body) = GalleryCoreAPI::fetchWebPage($fetch);
if ($success && !strncmp('PASS_REWRITE', $body, 12)) {
$ret = GalleryCoreApi::setPluginParameter(
'module', 'rewrite', 'modrewrite.status', serialize(array('needOptions' => true)));
if ($ret) {
return array($ret, null, null);
}
return array(null, REWRITE_STATUS_OK, REWRITE_STATUS_OK);
}
/*
* If we fail testing with the custom setup don't whine too much. Instead give the user
* directions to edit the custom .htaccess file and then test again.
*/
if ($target == 'custom') {
return array(null, isset($status['forced']) ? REWRITE_STATUS_OK
: REWRITE_STATUS_APACHE_UNABLE_TO_TEST,
REWRITE_STATUS_APACHE_UNABLE_TO_TEST);
}
return array(null, isset($status['forced']) ? REWRITE_STATUS_OK
: REWRITE_STATUS_APACHE_NO_MOD_REWRITE,
REWRITE_STATUS_APACHE_NO_MOD_REWRITE);
}
/**
* @see RewriteParser::loadTestResultsTemplate
*/
function loadTestResultsTemplate(&$template, &$form) {
global $gallery;
$urlGenerator =& $gallery->getUrlGenerator();
$baseUrlComponents = parse_url($urlGenerator->getCurrentUrlDir(true));
$TestResults = array();
/* Check Gallery .htaccess */
list ($ret, $TestResults['gallery']['htaccess']) = ModRewriteHelper::checkFile();
if ($ret) {
return $ret;
}
/* Check mod_rewrite */
list ($ret, $TestResults['gallery']['modRewrite'],
$TestResults['gallery']['trueModRewrite']) = ModRewriteHelper::checkModRewrite();
if ($ret) {
return $ret;
}
/* Check embedded .htaccess */
if (GalleryUtilities::isEmbedded()) {
$TestResults['embedded'] = array();
list ($ret, $TestResults['embedded']['htaccess']) = ModRewriteHelper::checkFile(true);
if ($ret) {
return $ret;
}
}
/* Get extra information if the .htaccess test fails */
if ($TestResults['gallery']['htaccess'] != REWRITE_STATUS_OK) {
list ($ret, $TestResults['gallery']['htaccessPath']) =
ModRewriteHelper::getHtaccessPath();
if ($ret) {
return $ret;
}
}
if (isset($TestResults['embedded']['htaccess'])
&& $TestResults['embedded']['htaccess'] != REWRITE_STATUS_OK) {
list ($ret, $TestResults['embedded']['htaccessPath']) =
ModRewriteHelper::getHtaccessPath(true);
if ($ret) {
return $ret;
}
}
/* Create test URLs for manually testing mod_rewrite */
if ($TestResults['gallery']['modRewrite'] != REWRITE_STATUS_OK
&& $TestResults['gallery']['modRewrite'] != REWRITE_STATUS_MULTISITE) {
if ($baseUrlComponents['path'] == '/gallery2') {
$target = 'gallery2';
} else if ($baseUrlComponents['path'] == '/gallery') {
$target = 'gallery';
} else {
$target = 'custom';
}
$TestResults['href']['test1'] = $urlGenerator->generateUrl(
array('href' => 'modules/rewrite/data/mod_rewrite/' . $target . '/Rewrite.txt'));
$TestResults['href']['test2'] = $urlGenerator->generateUrl(
array('href' => 'modules/rewrite/data/mod_rewrite_no_options/' .
$target . '/Rewrite.txt'));
}
/* Get the custom line and file instructions */
if ($TestResults['gallery']['modRewrite'] == REWRITE_STATUS_APACHE_UNABLE_TO_TEST) {
$TestResults['gallery']['customFile1'] = dirname(dirname(dirname(dirname(__FILE__)))) .
'/data/mod_rewrite/custom/.htaccess';
$TestResults['gallery']['customLine1'] = 'RewriteBase ' .
$baseUrlComponents['path'] . 'modules/rewrite/data/mod_rewrite/custom/';
$TestResults['gallery']['customFile2'] = dirname(dirname(dirname(dirname(__FILE__)))) .
'/data/mod_rewrite_no_options/custom/.htaccess';
$TestResults['gallery']['customLine2'] = 'RewriteBase ' .
$baseUrlComponents['path'] . 'modules/rewrite/data/mod_rewrite_no_options/custom/';
}
if ($TestResults['gallery']['modRewrite'] != REWRITE_STATUS_OK) {
$TestResults['action'] = 1;
$TestResults['refresh'] = 1;
} else if ($TestResults['gallery']['htaccess'] != REWRITE_STATUS_OK ||
(isset($TestResults['embedded']) &&
$TestResults['embedded']['htaccess'] != REWRITE_STATUS_OK)) {
$TestResults['refresh'] = 1;
}
$TestResults['template'] = 'modules/rewrite/templates/ModRewriteTestResults.tpl';
$template->setVariable('TestResults', $TestResults);
return null;
}
/**
* @see RewriteParser::loadAdminParserTemplate
*/
function loadAdminRewriteTemplate(&$template, &$form) {
global $gallery;
$urlGenerator =& $gallery->getUrlGenerator();
$AdminParser = array();
if (GalleryUtilities::isEmbedded()) {
if (empty($form['formName'])) {
list ($ret, $form['embeddedLocation']) = GalleryCoreApi::getPluginParameter(
'module', 'rewrite', 'modrewrite.embeddedLocation');
if ($ret) {
return $ret;
}
list ($ret, $form['embeddedHtaccess']) = GalleryCoreApi::getPluginParameter(
'module', 'rewrite', 'modrewrite.embeddedHtaccess');
if ($ret) {
return $ret;
}
}
$AdminParser['host'] = substr($urlGenerator->makeUrl('/'), 0, -1);
$AdminParser['action'] = 1;
$AdminParser['template'] = 'modules/rewrite/templates/ModRewriteAdminParser.tpl';
}
$template->setVariable('AdminParser', $AdminParser);
return null;
}
/**
* @see RewriteParser::fetchEmbedConfig
* @param array $param config values
* @param object ModRewriteParser $parser
* @param boolean $saveActiveRules true if we want to write the .htaccess
*/
function saveEmbedConfig($param, $parser, $saveActiveRules) {
global $gallery;
$platform =& $gallery->getPlatform();
if (empty($param['embeddedLocation']) || empty($param['embeddedHtaccess'])) {
return array(null, REWRITE_STATUS_EMPTY_VALUE);
}
$embeddedLocation = '/' . trim($param['embeddedLocation'], '/');
if ($embeddedLocation{strlen($embeddedLocation)-1} != '/') {
$embeddedLocation .= '/';
}
$embeddedHtaccess = rtrim($param['embeddedHtaccess'], '/');
if (!$platform->is_dir($embeddedHtaccess) ||
!$platform->is_writeable($embeddedHtaccess . '/.htaccess')) {
return array(null, REWRITE_STATUS_HTACCESS_CANT_WRITE);
}
$ret = GalleryCoreApi::setPluginParameter(
'module', 'rewrite', 'modrewrite.embeddedHtaccess', $embeddedHtaccess);
if ($ret) {
return array($ret, null);
}
$ret = GalleryCoreApi::setPluginParameter(
'module', 'rewrite', 'modrewrite.embeddedLocation', $embeddedLocation);
if ($ret) {
return array($ret, null);
}
if ($saveActiveRules) {
list($ret, $code) = $parser->saveActiveRules();
if ($ret) {
return array($ret, null);
}
}
return array(null, $code);
}
}
?>