Boucle de redirection sur prestashop en passant par un proxy

J’explique dans cet article comment visionner un site installé en local directement via un ipad (ou autre). Mais si le site en question est créé avec Prestashop vous allez vous retrouver avec une boucle de redirection sur le frontOffice (mais pas en backOffice), voici la solution.

Le problème vient du fait que le terminal qui se connecte au proxy redonne systématiquement le host complet comme url de requête au lieu de donner simplement le répertoire final.
Par conséquent la fonction « initialize » de la classe « Shop » tourne en boucle pour nettoyer l’url et génère la redirection qui pose problème.
Voici un override qui va vous permettre de passer outre ce problème:

A placer dans « override/classes/shop/Shop.php »


class Shop extends ShopCore
{

	/**
	 * Find the shop from current domain / uri and get an instance of this shop
	 * if INSTALL_VERSION is defined, will return an empty shop object
	 *
	 * @return Shop
	 */
	public static function initialize()
	{
		// Find current shop from URL
		if (!($id_shop = Tools::getValue('id_shop')) || defined('_PS_ADMIN_DIR_'))
		{
			$host = pSQL(Tools::getHttpHost());
			$sql = 'SELECT s.id_shop, CONCAT(su.physical_uri, su.virtual_uri) AS uri, su.domain, su.main
					FROM '._DB_PREFIX_.'shop_url su
					LEFT JOIN '._DB_PREFIX_.'shop s ON (s.id_shop = su.id_shop)
					WHERE (su.domain = \''.$host.'\' OR su.domain_ssl = \''.$host.'\')
						AND s.active = 1
						AND s.deleted = 0
					ORDER BY LENGTH(CONCAT(su.physical_uri, su.virtual_uri)) DESC';

			$id_shop = '';
			$found_uri = '';
			$request_uri = rawurldecode($_SERVER['REQUEST_URI']);
			$request_uri=str_replace('http://'.$_SERVER['HTTP_HOST'],'',$request_uri);
			$is_main_uri = false;
			if ($results = Db::getInstance()->executeS($sql))
			{
				foreach ($results as $row)
				{
					// An URL matching current shop was found
					//$request_uri='/index.php';
					
					if (preg_match('#^'.preg_quote($row['uri'], '#').'#i', $request_uri))
					{
						
						$id_shop = $row['id_shop'];
						$found_uri = $row['uri'];
						if ($row['main'])
							$is_main_uri = true;
						break;
					}
					
				}
			}
			// If an URL was found but is not the main URL, redirect to main URL
			if ($id_shop && !$is_main_uri)
			{
				foreach ($results as $row)
				{
					if ($row['id_shop'] == $id_shop && $row['main'])
					{
						// extract url parameters
						$request_uri = substr($request_uri, strlen($found_uri));
						$url = str_replace('//', '/', $row['domain'].$row['uri'].$request_uri);
						header('HTTP/1.1 301 Moved Permanently');
						header('Cache-Control: no-cache');
						header('location: http://'.$url);
						exit;
					}
				}
			}
		}
	
		if ((!$id_shop && defined('_PS_ADMIN_DIR_')) || Tools::isPHPCLI())
		{
			// If in admin, we can access to the shop without right URL
			if ((!$id_shop && Tools::isPHPCLI()) || defined('_PS_ADMIN_DIR_'))
				$id_shop = (int)Configuration::get('PS_SHOP_DEFAULT');

			$shop = new Shop((int)$id_shop);
			if (!Validate::isLoadedObject($shop))
				$shop = new Shop((int)Configuration::get('PS_SHOP_DEFAULT'));

			$shop->physical_uri = preg_replace('#/+#', '/', str_replace('\\', '/', dirname(dirname($_SERVER['SCRIPT_NAME']))).'/');
			$shop->virtual_uri = '';
			
			// Define some $_SERVER variables like HTTP_HOST if PHP is launched with php-cli
			if (Tools::isPHPCLI())
			{
				if (!isset($_SERVER['HTTP_HOST']) || empty($_SERVER['HTTP_HOST']))
					$_SERVER['HTTP_HOST'] = $shop->domain;
				if (!isset($_SERVER['SERVER_NAME']) || empty($_SERVER['SERVER_NAME']))
					$_SERVER['SERVER_NAME'] = $shop->domain;
				if (!isset($_SERVER['REMOTE_ADDR']) || empty($_SERVER['REMOTE_ADDR']))
					$_SERVER['REMOTE_ADDR'] = '127.0.0.1';
			}
		}
		else
		{
			
			$shop = new Shop($id_shop);
			
			if (!Validate::isLoadedObject($shop) || !$shop->active || !$id_shop)
			{
				// No shop found ... too bad, let's redirect to default shop
				$default_shop = new Shop(Configuration::get('PS_SHOP_DEFAULT'));

				// Hmm there is something really bad in your Prestashop !
				if (!Validate::isLoadedObject($default_shop))
					throw new PrestaShopException('Shop not found');

				$params = $_GET;
				unset($params['id_shop']);
				if (!Configuration::get('PS_REWRITING_SETTINGS'))
					$url = 'http://'.$default_shop->domain.$default_shop->getBaseURI().'index.php?'.http_build_query($params);
				else
				{
					// Catch url with subdomain "www"
					if (strpos($default_shop->domain, 'www.') === 0 && 'www.'.$_SERVER['HTTP_HOST'] === $default_shop->domain
						|| $_SERVER['HTTP_HOST'] === 'www.'.$default_shop->domain)
						$uri = $default_shop->domain.$_SERVER['REQUEST_URI'];
					else
						$uri = $default_shop->domain.$default_shop->getBaseURI();
					
					if (count($params))
						$url = 'http://'.$uri.'?'.http_build_query($params);
					else
						$url = 'http://'.$uri;
				}
				header('location: '.$url);
				exit;
			}
		}
		
		self::$context_id_shop = $shop->id;
		self::$context_id_shop_group = $shop->id_shop_group;
		self::$context = self::CONTEXT_SHOP;

		return $shop;
	}
}

Pour les curieux j’ai juste rajouté le code suivant à la ligne 27


$request_uri=str_replace('http://'.$_SERVER['HTTP_HOST'],'',$request_uri);

*** EDIT 23/02/15 ***
Si comme Fred vous avez un problème d’erreur 404 la solution est de désactiver la réécriture d’url et la redirection vers l’url canonique.

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *