Toutes les clefs pour réussir dans le e-commerce

Mes modules Prestashop

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.

Poster un Commentaire

1 Commentaire sur "Boucle de redirection sur prestashop en passant par un proxy"

Recevoir un email pour
avatar
Trier par:   plus récent | plus vieux | Plus de vote
Fred D.
Invité
Fred D.

Bonjour Olivier,
merci pour cette article !

Je rencontre néanmoins un problème à la suite de cette manip.
J’ai un domaineA (URL officielle) qui doit pointer sur domaineB.

Sur le domaineA j’ai le .htaccess suivant :
RewriteEngine on
RewriteCond %{HTTP_HOST} ^domaineA.com
RewriteRule ^(.*) http://domaineB.com/$1 [P]

J’ai bien modifié l’URL dans le BackOffice (dans Prefs SEO & URLs) pourqu’il pointe bien sur domaineA.com.

En allant sur l’URL http://www.domaineA.com j’arrive bien sur domaineB (en gardant domaineA.com dans la barre d’adresse). Ma boutique s’affiche mais avec une erreur 404 sur le contenu de la homepage.
J’ai l’impression que seuls les fichiers statiques fonctionnent mais pas toutes les URL ré-écrites par le htacess de la boutique (donc du domaineB).

Auriez-vous une solution à mon problème ?

Merci d’avance.

wpDiscuz