Example #1
0
/**
* Redirect browser to the new location
*
* @param string $location - destination of redirect
* @param bool $allow_external_redirect - allow redirection to external resource
* @param bool $is_permanent - if true, perform 301 redirect
* @return
*/
function fn_redirect($location, $allow_external_redirect = false, $is_permanent = false)
{
    $external_redirect = false;
    $protocol = defined('HTTPS') ? 'https' : 'http';
    $meta_redirect = false;
    // Cleanup location from & signs and call fn_url()
    $location = fn_url(str_replace(array('&', "\n", "\r"), array('&', '', ''), $location));
    // Convert absolute link with location to relative one
    if (strpos($location, '://') !== false || substr($location, 0, 7) == 'mailto:') {
        if (strpos($location, Registry::get('config.http_location')) !== false) {
            $location = str_replace(array(Registry::get('config.http_location') . '/', Registry::get('config.http_location')), '', $location);
            $protocol = 'http';
        } elseif (strpos($location, Registry::get('config.https_location')) !== false) {
            $location = str_replace(array(Registry::get('config.https_location') . '/', Registry::get('config.https_location')), '', $location);
            $protocol = 'https';
        } else {
            if ($allow_external_redirect == false) {
                // if external redirects aren't allowed, redirect to index script
                $location = '';
            } else {
                $external_redirect = true;
            }
        }
        // Convert absolute link without location to relative one
    } else {
        $_protocol = "";
        $_location = "";
        $http_path = Registry::get('config.http_path');
        $https_path = Registry::get('config.https_path');
        if (!empty($http_path) && substr($location, 0, strlen($http_path)) == $http_path) {
            $_location = substr($location, strlen($http_path) + 1);
            $_protocol = 'http';
        }
        if (!empty($https_path) && substr($location, 0, strlen($https_path)) == $https_path) {
            // if https path partially equal to http path check if https path is not just a part of http path
            // e. g. http://example.com/pathsimple & https://example.com/path
            if ($_protocol != 'http' || empty($http_path) || substr($http_path, 0, strlen($https_path)) != $https_path) {
                $_location = substr($location, strlen($https_path) + 1);
                $_protocol = 'https';
            }
        }
        $protocol = Registry::get('config.http_path') != Registry::get('config.https_path') && !empty($_protocol) ? $_protocol : $protocol;
        $location = !empty($_protocol) ? $_location : $location;
    }
    if ($external_redirect == false) {
        fn_set_hook('redirect', $location);
        $protocol_changed = defined('HTTPS') && $protocol == 'http' || !defined('HTTPS') && $protocol == 'https';
        // For correct redirection, location must be absolute with path
        $location = ($protocol == 'http' ? Registry::get('config.http_location') : Registry::get('config.https_location')) . '/' . ltrim($location, '/');
        // Parse the query string
        $fragment = '';
        $query_array = array();
        $parsed_location = parse_url($location);
        if (!empty($parsed_location['query'])) {
            parse_str($parsed_location['query'], $query_array);
            $location = str_replace('?' . $parsed_location['query'], '', $location);
        }
        if (!empty($parsed_location['fragment'])) {
            $fragment = '#' . $parsed_location['fragment'];
            $location = str_replace($fragment, '', $location);
        }
        if ($protocol_changed && (Registry::get('config.http_host') != Registry::get('config.https_host') || Registry::get('config.http_path') != Registry::get('config.https_path'))) {
            $query_array[Session::getName()] = Session::getId();
        }
        // If this is not ajax request, remove ajax specific parameters
        if (!defined('AJAX_REQUEST')) {
            unset($query_array['is_ajax']);
            unset($query_array['result_ids']);
        } else {
            $query_array['result_ids'] = implode(',', Tygh::$app['ajax']->result_ids);
            $query_array['is_ajax'] = Tygh::$app['ajax']->redirect_type;
            $query_array['full_render'] = !empty($_REQUEST['full_render']) ? $_REQUEST['full_render'] : false;
            $query_array['callback'] = Tygh::$app['ajax']->callback;
            $ajax_assigned_vars = Tygh::$app['ajax']->getAssignedVars();
            if (!empty($ajax_assigned_vars['html'])) {
                unset($ajax_assigned_vars['html']);
            }
            $query_array['_ajax_data'] = $ajax_assigned_vars;
        }
        if (!empty($query_array)) {
            $location .= '?' . http_build_query($query_array) . $fragment;
        }
        // Redirect from https to http location
        if ($protocol_changed && defined('HTTPS')) {
            $meta_redirect = true;
        }
    }
    fn_set_hook('redirect_complete', $meta_redirect);
    if (!defined('AJAX_REQUEST') && Embedded::isEnabled()) {
        if (strpos($location, Registry::get('config.http_location')) === 0) {
            $location = str_replace(Registry::get('config.http_location'), '', $location);
        } elseif (strpos($location, Registry::get('config.https_location')) === 0) {
            $location = str_replace(Registry::get('config.https_location'), '', $location);
        }
        $location = Embedded::getUrl() . '#!' . urlencode($location);
        $meta_redirect = true;
    }
    if (defined('AJAX_REQUEST')) {
        // make in-script redirect during ajax request
        $_purl = parse_url($location);
        $_GET = array();
        $_POST = array();
        if (!empty($_purl['query'])) {
            parse_str($_purl['query'], $_GET);
        }
        $_REQUEST = Bootstrap::safeInput($_GET);
        $_SERVER['REQUEST_METHOD'] = 'GET';
        $_SERVER['REQUEST_URI'] = $_purl['path'];
        $_SERVER['QUERY_STRING'] = !empty($_purl['query']) ? $_purl['query'] : '';
        fn_get_route($_REQUEST);
        Registry::save();
        // save registry cache to execute cleanup handlers
        fn_init_settings();
        fn_init_addons();
        Registry::clearCacheLevels();
        Tygh::$app['ajax']->updateRequest();
        return fn_dispatch();
    } elseif (!ob_get_contents() && !headers_sent() && !$meta_redirect) {
        if ($is_permanent) {
            header('HTTP/1.0 301 Moved Permanently');
        }
        header('Location: ' . $location);
        exit;
    } else {
        $delay = (Debugger::isActive() || fn_is_development()) && !Registry::get('runtime.comet') ? 10 : 0;
        if ($delay != 0) {
            fn_echo('<a href="' . htmlspecialchars($location) . '" style="text-transform: lowercase;">' . __('continue') . '</a>');
        }
        fn_echo('<meta http-equiv="Refresh" content="' . $delay . ';URL=' . htmlspecialchars($location) . '" />');
    }
    fn_flush();
    exit;
}