<?php
/*
 * $RCSfile: RewriteUrlGenerator.class,v $
 *
 * Gallery - a web based photo album viewer and editor
 * Copyright (C) 2000-2005 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.
 */
/**
 * @package Rewrite
 * @version $Revision: 1.24 $ $Date: 2005/08/26 19:24:41 $
 * @author Douglas Cau <douglas@cau.se>
 */

/**
 * Required class
 */
GalleryCoreApi::relativeRequireOnce('modules/core/classes/GalleryUrlGenerator.class');
GalleryCoreApi::relativeRequireOnce('modules/rewrite/classes/RewriteMap.class');

/**
 * Url Generator
 *
 * @package Rewrite
 * @subpackage Classes
 */
class RewriteUrlGenerator extends GalleryUrlGenerator {

    /**
     * If there's an error, use parent GalleryUrlGenerator functions.
     *
     * @var bool has an error occured?
     * @access private
     */
    var $_error = false;

    /**
     * Short URL map.
     *
     * @var array of view => short URL pattern
     * @access private
     */
    var $_shortUrls = array();

    /**
     * @see GalleryUrlGenerator::init
     */
    function init($baseFile=null, $embedPath=null, $relativeG2Path=null, $embedSessionString=null) {
	parent::init($baseFile, $embedPath, $relativeG2Path, $embedSessionString);

	list($ret, $this->_shortUrls) = RewriteMap::getShortUrls();
	if ($ret->isError()) {
	    $this->_error = true;
	}
    }

    /**
     * @see GalleryUrlGenerator::getCurrentUrl
     */
    function getCurrentUrl() {
	if ($this->_error) {
	    return parent::getCurrentUrl();
	}

	if (empty($this->_currentUrl)) {
	    if (GalleryUtilities::isEmbedded() && !empty($this->_embedPath)) {
		$path = $this->_embedPath;
	    } else {
		$location = GalleryUtilities::isEmbedded() ? 'embeddedLocation' : 'galleryLocation';
		list ($ret, $path) =
			GalleryCoreApi::getPluginParameter('module', 'rewrite', $location);
		if ($ret->isError() || empty($path)) {
		    /*
		     * We dont know where we're at. This could happen if rewrite was installed
		     * in G2 standalone, and now is accessed as G2 embedded. Turn off short URLs
		     * for the embedded mode and wait until the user has set it up corectly.
		     */
		    $this->_error = true;
		    return parent::getCurrentUrl();
		}
	    }

	    $tmp = $path . $this->_baseFile;
	    $queryString = GalleryUtilities::getServerVar('QUERY_STRING');
	    if (!empty($queryString)) {
		$tmp .= '?' . GalleryUtilities::htmlEntityDecode($queryString);
	    }

	    $this->_currentUrl = $this->makeUrl($tmp);
	}

	return $this->_currentUrl;
    }

    /**
     * @see GalleryUrlGenerator::getNavigationReturnUrl
     */
    function getNavigationReturnUrl() {
	$formUrl = GalleryUtilities::getRequestVariables('formUrl');
	if (!empty($formUrl)) {
	    /*
	     * We don't really have an URL, because we are in a POST request.
	     * This is the last known URL when the form was originally rendered:
	     */
	    return $formUrl;
	}

	/*
	 * Lets strip out all unnecessary params and regenerate the url. Otherwise we
	 * wont get a short URL if possible.
	 */
	$params = array();
	$urlVariables = GalleryUtilities::getUrlVariablesFiltered(
			array('return', 'returnName', 'navId', 'fromNavId', 'path'));
	foreach ($urlVariables as $key => $value) {
	    $params[substr($key, strlen(GALLERY_FORM_VARIABLE_PREFIX))] = $value;
	}
	$url = $this->generateUrl($params);

	return $url;
    }

    /**
     * @see GalleryUrlGenerator::generateUrl
     */
    function generateUrl($params=array(), $forceSessionId=null) {
	if ($this->_error) {
	    return parent::generateUrl($params, $forceSessionId);
	}

	if (isset($params['view'])) {
	    $index = $params['view'];
	    if (isset($params['subView'])) {
		$index .= '|' . $params['subView'];
	    }
	}

	/* Build the short style URL */
	if (isset($index) && isset($this->_shortUrls[$index]) && !isset($params['href'])) {
	    /* Navigation */
	    global $gallery;
	    $currentView = $gallery->getCurrentView();
	    if (!empty($this->_navId) && (empty($currentView) ||
		    $currentView == $params['view'] || !empty($params['controller']))) {
		/*
		 * We are moving around in the same view or we are redirecting to a controller,
		 * who knows where it will redirect to.  Let's keep the navigation.
		 */
		$params['navId'] = $this->_navId;
	    }

	    /* Check if we are forced to append the session id in embedded G2 */
	    if ($this->embedForceSessionId($params)) {
		$forceSessionId = true;
	    }

	    $url = $this->_shortUrls[$index];
	    $entity = null;
	    $itemId = isset($params['itemId']) ? $params['itemId'] : null;

	    preg_match_all('/%([a-z]+)%/i', $url, $regs);
	    foreach ($regs[1] as $arg) {
		switch ($arg) {
		case 'path':
		    if ((!isset($entity) && !$this->_loadEntity($itemId, $entity)) ||
			    !GalleryUtilities::isA($entity, 'GalleryFileSystemEntity')) {
			return parent::generateUrl($params, $forceSessionId);
		    }
		    list ($ret, $path) = $entity->fetchLogicalPath();
		    if ($ret->isError()) {
			return parent::generateUrl($params, $forceSessionId);
		    }

		    if (substr($url, -6) != '%path%') {
			/* Trim / off end of path if rule has a suffix */
			if ($path != '/') {
			    $path = rtrim($path, '/');
			} else {
			    $url = str_replace('%path%/', '%path%', $url);
			}
		    } else if (!GalleryUtilities::isA($entity, 'GalleryAlbumItem')) {
			/* Append .html suffix on non-album paths if rule has no suffix */
			$path .= '.html';
		    }
		    /* urlencode except for path separators(/) */
		    $url = str_replace('%path%',
			str_replace('%2F', '/', urlencode(substr($path, 1))), $url);
		    unset($params['itemId']);
		    break;

		case 'fileName':
		    if (!isset($entity) && !$this->_loadEntity($itemId, $entity)) {
			return parent::generateUrl($params, $forceSessionId);
		    }
		    list ($ret, $pseudoFileName) = GalleryUtilities::getPseudoFileName($entity);
		    if ($ret->isError()) {
			return parent::generateUrl($params, $forceSessionId);
		    }
		    $url = str_replace('%fileName%', urlencode($pseudoFileName), $url);
		    break;

		case 'serialNumber':
		    if (!isset($entity) && !$this->_loadEntity($itemId, $entity)) {
			return parent::generateUrl($params, $forceSessionId);
		    }
		    $url = str_replace('%serialNumber%', $entity->getSerialNumber(), $url);
		    unset($params['serialNumber']);
		    break;

		default:
		    $url = str_replace('%' . $arg . '%', urlencode($params[$arg]), $url);
		    unset($params[$arg]);
		}
	    }

	    unset($params['view']);
	    unset($params['subView']);

	    if (empty($url)) {
		$url = $this->_baseFile;
	    }

	    return parent::generateUrl($params, $forceSessionId, $this->getCurrentUrlDir() . $url);
	}

	return parent::generateUrl($params, $forceSessionId);
    }

    /**
     * @return boolean true on success
     * @access private
     */
    function _loadEntity(&$itemId, &$entity) {
	/* Assume rootAlbum if itemId not specified */
	if (empty($itemId)) {
	    list ($ret, $itemId) =
		GalleryCoreApi::getPluginParameter('module', 'core', 'id.rootAlbum');
	    if ($ret->isError()) {
		return false;
	    }
	}

	list ($ret, $entity) = GalleryCoreApi::loadEntitiesById($itemId);
	if ($ret->isError()) {
	    return false;
	}
	return true;
    }
}
?>
