Why Prestashop doesn't redirect? - php

I have a module that call the Tools::redirect($myurl) function.
If I debug in that function (file /classes/Tools.php) :
public static function redirect($url, $base_uri = __PS_BASE_URI__, Link $link = null, $headers = null)
{
if (!$link)
$link = Context::getContext()->link;
if (strpos($url, 'http://') === false && strpos($url, 'https://') === false && $link)
{
if (strpos($url, $base_uri) === 0)
$url = substr($url, strlen($base_uri));
if (strpos($url, 'index.php?controller=') !== false && strpos($url, 'index.php/') == 0)
{
$url = substr($url, strlen('index.php?controller='));
if (Configuration::get('PS_REWRITING_SETTINGS'))
$url = Tools::strReplaceFirst('&', '?', $url);
}
$explode = explode('?', $url);
// don't use ssl if url is home page
// used when logout for example
$use_ssl = !empty($url);
$url = $link->getPageLink($explode[0], $use_ssl);
if (isset($explode[1]))
$url .= '?'.$explode[1];
}
// Send additional headers
if ($headers)
{
if (!is_array($headers))
$headers = array($headers);
foreach ($headers as $header)
header($header);
}
header('Location: '.$url);
exit;
}
setting a die('test'); the line before the header("location"), I have my debug. If I put my test between header() and exit; I still have my test.
So far, everything seems normal. Nevertheless, my URL in the variable is http://www.example.com/connexion?back=http://www.example.com/1-my-category and my browser displays a 403 forbidden page. If I cut/paste the URL in the variable, it will display the login form. So, why the header location is not redirecting me to the page ? I'm getting lost...

Solved! The 403 redirection was in the CategoryController in case of user not logged. So I override the controller redirecting to my login page if user is not logged.

Related

Cannot redirect correctly with PHP

I have a blog in a website that I want to redirect.
For example this URL https://example.com/blog/june-2021/name-of-blog-post should redirect to https://example2.com/blog/june-2021/name-of-blog-post
There are hundreds of blog posts so I can't use an array to redirect them one by one.
I'm using Pantheon as the host. I added the script to settings.php.
Currently everything from example.com goes to example2.com, so it's not working correctly.
Here's my script:
$url = $_SERVER['REQUEST_URI'];
$uri_path = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
$uri_segments = explode('/', $uri_path);
$blog = $uri_segments[0];
$post_date = $uri_segments[1];
$post_name = $uri_segments[2];
if ((stripos($url, "/blog/") === 0) && (php_sapi_name() != "cli")) {
header('HTTP/1.0 301 Moved Permanently'); header("Location: https://example2.com".$blog.$post_date.$post_name);
if (extension_loaded('newrelic')) {
newrelic_name_transaction("redirect");
}
exit(); }
Thanks in advance!
You can check for /blog/ by checking that it is found !== false anywhere in $_SERVER['REQUEST_URI']:
if ((stripos($url, "/blog/") !== false) && (php_sapi_name() != "cli")) {
Or check to see if it is found at the first 0 position of $_SERVER['REQUEST_URI']:
if ((stripos($url, "/blog/") === 0) && (php_sapi_name() != "cli")) {
Notes:
stripos only takes three arguments and you only need the first two.
Location header should consist of a single absolute URI like https://example2.com/blog/june-2021/name-of-blog-post, so you might look at the other $_SERVER variables to construct one.

how to pass variables from controller to controller in prestashop?

is there a way to pass variables from a controller to another in prestashop? I'm tring to pass the new_address variable on an AddressController override like this:
Tools::redirect('index.php?controller='.$back.($mod ? '&back='.$mod : '') . '&new_address=' . $address->id);
NOTE that this is the original line + . '&new_address=' . $address->id, so I have to stick to Tools::redirect.
By using that line, no new_address is found on the next page in $_GET. From OrderController and ParentOrderController too, I don't see it.
I've found the reason in Tools::redirect. It has a line like this:
$url = Tools::strReplaceFirst('&', '?', $url);
here they are basically excluding any queryvar other than the first one, so you won't find any if you add some. If you have index.php?a=1&b=2, you'll get index.php?a=1?b=2. I don't really see the point... Maybe it's a bug.
So I overridden Tools::redirect like this (modded lines are commented):
public static function redirect($url, $base_uri = __PS_BASE_URI__, Link $link = null, $headers = null){
if (!$link) $link = Context::getContext()->link;
$querystring = array_pop(explode('?', $url)); // MOD: Save the original querystring. I take the last item in array because sometimes (i think it's a bug) the $url is like index.php?controller=order.php?step=1, so 2 question marks.
if (strpos($url, 'http://') === false && strpos($url, 'https://') === false && $link) {
if (strpos($url, $base_uri) === 0) {
$url = substr($url, strlen($base_uri));
}
if (strpos($url, 'index.php?controller=') !== false && strpos($url, 'index.php/') == 0) {
$url = substr($url, strlen('index.php?controller='));
if (Configuration::get('PS_REWRITING_SETTINGS')) {
$url = Tools::strReplaceFirst('&', '?', $url); // ...Don't see the point here...
}
}
$explode = explode('?', $url);
// don't use ssl if url is home page
// used when logout for example
$use_ssl = !empty($url);
$url = $link->getPageLink($explode[0], $use_ssl);
if($querystring) $url .= '?'.$querystring; // MOD: adding full querystring!! Also deleted 3 lines that added $explode[1] instead
}
// Send additional headers
if ($headers) {
if (!is_array($headers)) $headers = array($headers);
foreach ($headers as $header) {
header($header);
}
}
header('Location: '.$url);
exit;
}

Check URL for valid format by pattern

I have social bookmarking website and in this website users can submit link from others website (using booklet or bookmark button in bookmark bar, or by adding URLs in direct method).
The users have problem with some URLs when they add links with bookmark button in their browsers. The problem occurs with URLs that contain "&" character. Most of the users who work with Safari on Mac or Windows can not add such link with bookmark button.
Issue is that all URLs with "&" end up with $isLink = preg_match($pattern, $url); // Returns false (see the code below).
I removed part of my code (see comments in the snippet), and that fixed the problem.
But I do not want to remove this code. How can I fix the problem without removing it?
$url = htmlspecialchars(sanitize($_POST['url'], 3));
$url = str_replace('&', '&', $url);
$url = html_entity_decode($url);
if (strpos($url,'http')!==0) {
$url = "http://$url";
}
// check if URL is valid format
$pattern = '/^(([\w]+:)?\/\/)?(([\d\w]|%[a-fA-f\d]{2,2})+(:([\d\w]|%[a-fA-f\d]{2,2})+)?#)?([\d\w]([-\d\w]{0,253}[\d\w])?\.)+[\w]{2,4}(:[\d]+)?(\/([-+_~.,\d\w]|%[a-fA-f\d]{2,2})*)*(\?(&?([-+_~.,\d\w]|%[a-fA-f\d]{2,2})=?)*)?(#([-+_~.,\/\d\w]|%[a-fA-f\d]{2,2})*)?$/';
// vvv I REMOVED FROM HERE vvv
$isLink = preg_match($pattern, $url); // Returns true if a link
// ^^^ UNTIL HERE ^^^
if($url == "http://" || $url == "") {
if(Submit_Require_A_URL == false) {
$linkres->valid = true;
} else {
$linkres->valid = false;
}
$linkres->url_title = "";
} elseif ($isLink == false) {
$linkres->valid = false;
}
Website bookmark button code is:
javascript:q=(document.location.href);void(open('http://website.com/submit.php?url='+escape(q),'_self','resizable,location,menubar,toolbar,scrollbars,status'));
Why are you not using the PHP function "filter_var()" to check the url:
$url = $_POST['url'];
$isLink = filter_var($url, FILTER_VALIDATE_URL);

php: Ensure redirection URL is inside domain

Suppose I have a function that redirects the page to the given URL (code below). For security reasons, I want to modify it so that it redirects only to the URLs inside my domain.
public static function redirect($num, $url)
{
header($http[$num]);
header ("Location: $url");
}
This is based more like TimWolla's example:
public static function redirect( $num, $url ) {
$host = ( parse_url( $url, PHP_URL_HOST );
if ( !empty( $host ) && $host == $_SERVER[ 'HTTP_HOST' ] ) {
$url = preg_replace( '/[^\w\s\p{L}\d\r?,=#:\/.-]/i', '', urldecode( $url ) );
#header( $http[ $num ] ); //not sure what this is for?
header( "Location: " . $url );
return;
} else return
}
All I have changed is rather than posting an error, the function just returns. Also added a filter to remove characters using a whitelist method.
The concept above is principle to build upon I think.
Use parse_url():
public static function redirect($num, $url)
{
if (parse_url($url, PHP_URL_HOST) != 'example.com') {
trigger_error("Invalid redirection-URL given", E_USER_ERROR);
return;
}
header($http[$num]);
header ("Location: $url");
}
Take a look at http://php.net/manual/en/reserved.variables.server.php.
You can find the host name there and then just do a strpos to ensure that the $url matches
you can find out your current host using $_SERVER['HTTP_HOST'] so you can check if the url contains the host before deciding what to do with it
$pos = strpos($url, $_SERVER['HTTP_HOST']);
if ($pos === false) {
//not on same domain don't redirect
} else {
//on same domain so do redirection
}
I would keep it as simple as possible, using strpos:
if ( strpos( $url, 'yourdomain.com' ) === false )
header('Location: /an/error/page.html');
else
header('Location: '.$url);

PHP check if referral url is the homepage

I'm trying to figure out how to check if the referral url to one of my inner pages is the homepage. This would be easy if the homepage was always www.mysite.com/index.php but what happens when it's simply www.mysite.com?
I know I could simply do
$url = $_SERVER['HTTP_REFERER'];
$pos = strrpos($url, "/");
$page = substr($url, $pos+1, (strlen($url)-$pos+1));
if (substr_count($url, 'index')) echo 'from index ';
but I don't have the index.php in my $url variable.
parse_url() can help you here.
// An array of paths that we consider to be the home page
$homePagePaths = array (
'/index.php',
'/'
);
$parts = parse_url($_SERVER['HTTP_REFERER']);
if (empty($parts['path']) || in_array($parts['path'], $homePagePaths)) echo 'from index';
N.B. This should not be relied upon for anything important. The Referer: header may be missing from the request, and can easily be spoofed. All major browsers should do what you expect them to, but hackers and webcrawlers may not.
Use this
if($_SERVER["REQUEST_URI"] == "/" || $_SERVER["REQUEST_URI"] == "/index.php")
echo "Home";
$url = parse_url($_SERVER['HTTP_REFERER']);
$url = explode('/',$url['path']);
if ($url[1]=='index.html'||empty($url[1])) echo 'from index ';
$referer = $_SERVER['HTTP_REFERER'];
$homepage = "index.php";
$ref_array = explode("/", $referer);
if(trim($ref_array[1]) == trim($homepage) || trim($ref_array[1]) == "") echo "From URL";
You should note that yoursite.com/index.php and yoursite.com/ is the same!
This would work:
if ($_SERVER['REQUEST_URI'] == '/')

Categories