ElixirVault/www/system-brs-core/library/cUrl/cUrl.php

552 lines
20 KiB
PHP

<?php
namespace BRSystems\Core\Library\cUrl;
use BRSystems\Core\Sys\sysLanguages\inc\sysLanguagesModule;
/**
* cUrl class with methods
*
* @category CMS
* @author Mareks Keišs <mareks.keiss@brsystems.lv>
* @since Version 1.0
*/
class cUrl
{
public $_endSlash;
public $_showDefault;
public $_url;
public $_is_cms;
public $_default;
public $_uri_lang;
public $_is_mobile;
public $_has_lang;
public $_visible = true;
public $_redirect_return = false;
public $_uri_lang_default = false;
public $_ssl = false;
public $_sslS = '';
public $_base_key = 'www';
public $_mobile_redirect = false;
public $_mobile_key = 'm';
public array $_mobile_key_exclude = ['kam'];
// Keys for switching between mobile & desktop views
public $_mobile_switch_key = 'sw';
public $_desktop_switch_key = 'dsw';
public $_url_param_sep = ':';
public array $_uri_struct = [
'params' => false,
'chunks' => false
];
public array $excludeIP = [
'83.241.17.142',
'192.168.8.114',
'192.168.88.153',
'80.232.245.53',
];
public array $excludeActions = [
'addToCart',
];
public array $excludeDomains = [
'kam.elixirvault.lv',
'local.elixirvault.lv'
];
public function __construct()
{
$this->_default = false;
$this->_has_lang = false;
$this->_endSlash = false;
$this->_showDefault = false;
$this->_ssl = !empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443;
if ($this->_ssl) {
$this->_sslS = 's';
}
if (defined('EXCLUDE_WWW_REDIRECT')) {
$this->excludeDomains = $this->excludeDomains + (is_array(EXCLUDE_WWW_REDIRECT) ? EXCLUDE_WWW_REDIRECT : array());
}
}
/**
* Function to check user for rights to do sth.
*
* @author Mareks Keišs <mareks.keiss@brsystems.lv>
* @category Module
* @param bool $bCmsSideUrl - is url from cms side
* @param bool|string $sAdminFolder - is url from cms side
* @param bool $passedURI - is url from cms side
* @return bool - true / false
*/
public function parseUrl(&$bCmsSideUrl = false, $sAdminFolder = false, $passedURI = false)
{
$red_params = '';
if (!($uri = $passedURI)) {
$uri = $_SERVER['REQUEST_URI'];
}
// Strip params & preserve for redirect set to variable
if (count($chunks = explode('?', $uri)) > 1) {
$uri = $chunks[0];
$red_params = '?' . $chunks[1];
}
// Recreate uri & split into parts
if ($red_params) {
$uri .= $red_params;
}
$normalized_uri = preg_replace('/\/+$/', '', $uri);
$chunks = explode('?', $normalized_uri);
// Handle language in the uri
$this->addLanguageToUri($chunks, $sAdminFolder);
$bCmsSideUrl = $this->_is_cms;
// Get parameter like param:value - erase from url
$map = explode('/', $chunks[0]);
foreach ($map as $k => $v) {
if (strpos($v, $this->_url_param_sep)) {
$params = explode($this->_url_param_sep, $v);
if (strlen($params[0])) {
$_GET[$params[0]] = $params[1];
}
unset($map[$k]);
} else if (!strlen($v)) {
unset($map[$k]);
}
}
// Found a module - analyse / else redirect to index
if (!count($map)) {
$map[] = 'index';
$this->_visible = false;
}
// Check backslash at the end & redirect if necessary
if (!getV('ajax') && !getV('cron')) {
if (
$this->_endSlash &&
substr($uri, strlen($uri) - 1) != '/'
) {
if ($this->_redirect_return) {
return $uri . '/' . $red_params;
}
redirectToUri($uri . '/' . $red_params);
} else if (
!$this->_endSlash &&
substr($uri, -1) == '/' &&
!is_dir(str_replace('//', '/', __MDIR__ . $uri))
) {
if ($this->_redirect_return) {
return substr($uri, 0, strlen($uri) - 1) . $red_params;
}
redirectToUri(substr($uri, 0, strlen($uri) - 1) . $red_params);
}
}
// Check if mobile request detected - then redirect
if (
$this->_mobile_redirect
&& $_SERVER['REMOTE_ADDR'] != '127.0.0.1'
&& $_SERVER['SERVER_ADDR'] !== $_SERVER['REMOTE_ADDR']
&& !in_array($_SERVER['SERVER_ADDR'], $this->excludeIP)
) {
$this->chkIsMobileDeviceRequest();
} else {
// Back to base url
if ($this->chkIsMobileView()) {
redirectToUri($this->getMobileDesktopRedirectUrl(false));
}
}
// WWW redirect
if (!$this->chkIsMobileView()) {
if (
$_SERVER['REMOTE_ADDR'] != '127.0.0.1'
&& $_SERVER['SERVER_ADDR'] !== $_SERVER['REMOTE_ADDR']
&& !in_array($_SERVER['SERVER_ADDR'], $this->excludeIP)
&& (!defined('NO_SSL') || defined('NO_SSL') && !NO_SSL)
&& !in_array(getV('action'), $this->excludeActions)
&& !in_array($_SERVER['HTTP_HOST'], $this->excludeDomains)
) {
if (isset($_SERVER['HTTP_HOST'])) {
// Route all through https
$addWWW = (substr($_SERVER['HTTP_HOST'], 0, 3) != 'www' ? 'www.' : '');
//------------------------------------------------------------
// Always use SSL
//------------------------------------------------------------
/*if(!$this->_ssl)
redirectToUri("https://{$addWWW}{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}");
elseif(isset($_SERVER['HTTP_HOST']) && $addWWW){
redirectToUri("https://{$addWWW}{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}");
}*/
//------------------------------------------------------------
// Key based page SSL usage
//------------------------------------------------------------
/* $keyPage = (strpos($uri, 'konts') == 1 || strpos($uri, 'forcehttps') || strpos($uri, 'kpsadmin') == 1 ? true : false);
if($keyPage && !$this->_ssl){
redirectToUri("https://{$addWWW}{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}");
}elseif(!$keyPage && $this->_ssl){
redirectToUri("http://{$addWWW}{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}");
}elseif($addWWW){
redirectToUri("http://{$addWWW}{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}");
}*/
}
}
}
$this->_url = '/' . implode('/', $map) . '/';
return true;
}
/**
* Function to check if mobile device sent request
*
* @author Mareks Keišs <mareks.keiss@brsystems.lv>
* @category Module
* @return bool true or false
*/
const VIEW_MOBILE = 2;
const VIEW_DESKTOP = 3;
public function chkIsMobileDeviceRequest() {
//session_destroy();
$bMobileView = false;
if(isset($_SERVER['HTTP_USER_AGENT'])){
$UserAgent = $_SERVER['HTTP_USER_AGENT'];
// http://detectmobilebrowsers.com/
$bMobileView = preg_match('/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i', $UserAgent)
|| preg_match('/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i', substr($UserAgent, 0, 4));
// Save user agent & check if agent changed
if(empty($_SESSION['user_agent'])){
$_SESSION['user_agent'] = $UserAgent;
$_SESSION['user_agent_manual_switched_to'] = false;
$_SESSION['user_device_is_mobile'] = $bMobileView;
}
if(getG($this->_mobile_switch_key, false) || getG($this->_desktop_switch_key, false)){
$_SESSION['user_agent_manual_switched_to'] = true;
}
// Automatic redirect
if(!$_SESSION['user_agent_manual_switched_to']){
if($bMobileView){
$this->redirectToMobileUrlAndBack();
}else{
$this->redirectToMobileUrlAndBack(false);
}
}else{
// Check if page switch accrued by referer
if(!empty($_SERVER['HTTP_REFERER'])){
// Distinguish mobile from desktop switch
if(getG($this->_mobile_switch_key, false)){
$_SESSION['user_agent_manual_switched_to'] = self::VIEW_MOBILE;
redirectToUri($this->getMobileDesktopRedirectUrl());
}else if(getG($this->_desktop_switch_key, false)){
$_SESSION['user_agent_manual_switched_to'] = self::VIEW_DESKTOP;
redirectToUri($this->getMobileDesktopRedirectUrl(false));
}
}
}
}
return $bMobileView;
}
/**
* Function to add / remove language to the url
*
* @author Mareks Keišs <mareks.keiss@brsystems.lv>
* @category Module
* @param mixed $uriCh - by ref url chunks
* @param string $sAdminFolder - admin folder string
* @return bool - true / false
*/
private function addLanguageToUri(&$uriCh, $sAdminFolder){
$params = '';
$uri = '';
if(count($uriCh)){
$uri = preg_replace('/\/+$/', '', $uriCh[0]);
}
if(count($uriCh)>1){
$params = '?' . $uriCh[1];
}
$chunks = array_filter(explode('/', $uri));
// Check passed url for cms indication
$this->_is_cms = ($sAdminFolder && current($chunks) == $sAdminFolder) ? true : false;
$lang_code = end($chunks);
// Check & set language
$oLangMod = new sysLanguagesModule();
$vLang = $oLangMod->getLangDataByCode($lang_code, $this->_is_cms);
if(strlen($lang_code) == 2 && !!$vLang){
array_pop($chunks);
if($vLang['default'] && !$this->_showDefault){
// Redirect & hide default language
$uri = "http{$this->_sslS}://{$_SERVER['HTTP_HOST']}/" . implode('/', $chunks) . $params;
if($this->_redirect_return) return $uri;
redirectToUri($uri);
}
// Set uri without language
$this->_has_lang = true;
$this->_uri_lang = $vLang;
$this->_uri_lang_default = $vLang['default'];
$uriCh[0] = '/' . implode('/', $chunks);
}else{
if($vLang = $oLangMod->getDefaultAppLang($this->_is_cms)){
$this->_uri_lang = $vLang;
$this->_uri_lang_default = 1;
}
if($this->_showDefault){
$uri = "http{$this->_sslS}://{$_SERVER['HTTP_HOST']}/" . implode('/', $chunks) . '/' . $this->_uri_lang['lang_code'] . $params;
redirectToUri($uri);
}
}
// Save in class varibles
$this->_uri_struct['params'] = $params;
$this->_uri_struct['chunks'] = $chunks;
return true;
}
/**
* Function to redirect & show default language
*
* @author Mareks Keišs <mareks.keiss@brsystems.lv>
* @category Module
* @return bool - true / false
*/
public function redirectToDefaultLang(){
// Get default language & redirect
if($this->_showDefault && !$this->_has_lang && $this->_uri_lang && $this->_uri_struct['chunks']){
}
}
/**
* Function to redirect & hide any language for CMS side
*
* @author Mareks Keišs <mareks.keiss@brsystems.lv>
* @category Module
* @return bool - true / false
*/
public function redirectToNoLang(){
// Get default language & redirect
if($this->_has_lang && $this->_uri_struct['chunks']){
$uri = "http{$this->_sslS}://" . $_SERVER['HTTP_HOST'] . implode('/', $this->_uri_struct['chunks']) . $this->_uri_struct['params'];
redirectToUri($uri);
}
}
/**
* Function to get language locale code for frontend
*
* @author Mareks Keišs <mareks.keiss@brsystems.lv>
* @category Module
* @return bool - true / false
*/
public function getAppLangLocale(){
// Get default language & redirect
if(isset($this->_uri_lang['lang_locale']) && $this->_uri_lang['lang_locale']){
return $this->_uri_lang['lang_locale'];
}else{
return false;
}
}
/**
* Function to get language locale code for frontend
*
* @author Mareks Keišs <mareks.keiss@brsystems.lv>
* @category Module
* @return void
*/
public function redirectToDomain(): void
{
// Get default language & redirect
$code = '';
if (isset($this->_uri_lang['lang_code']) && $this->_uri_lang['lang_code']) {
$code = $this->_uri_lang['lang_code'];
}
redirectToUri('/' . $code);
}
/**
* Function to check if we are in mobile view on desktop view
*
* @author Mareks Keišs <mareks.keiss@brsystems.lv>
* @category Module
* @param string|bool $host - host to check against
* @return bool - true / false (returns default TRUE - in case no action / redirect is necessary)
*/
public function chkIsMobileView($host = false){
$host = ($host ? str_replace(array('http://', 'https://'), '', $host) : $_SERVER['HTTP_HOST']);
$vTmp = explode('.', $host);
$sSubDomain = array_shift($vTmp);
if(!in_array($sSubDomain, $this->_mobile_key_exclude))
return substr($host, 0, strlen("{$this->_mobile_key}.")) == "{$this->_mobile_key}.";
return true;
}
public function chkIsDesktopView($host = false){
$host = ($host ? str_replace(array('http://', 'https://'), "", $host) : $_SERVER['HTTP_HOST']);
$vTmp = explode('.', $host);
$sSubDomain = array_shift($vTmp);
if(!in_array($sSubDomain, $this->_mobile_key_exclude))
return substr($host, 0, strlen("{$this->_base_key}.")) == "{$this->_base_key}.";
return true;
}
/**
* Function to redirect current view to mobile view
*
* @author Mareks Keišs <mareks.keiss@brsystems.lv>
* @category Module
*/
public function redirectToMobileUrlAndBack($bToMobile = true){
if($bToMobile){
// Check are we already mobile view
if(!$this->chkIsMobileView())
redirectToUri($this->getMobileDesktopRedirectUrl());
}else{
if(!$this->chkIsDesktopView())
redirectToUri($this->getMobileDesktopRedirectUrl(false));
}
}
/**
* Function to get device url
*
* @author Mareks Keišs <mareks.keiss@brsystems.lv>
* @category Module
*/
public function getMobileDesktopRedirectUrl($bMobile = true, $bManualSwitch = false){
// Match domain
preg_match("/(?P<domain>[a-z0-9][a-z0-9\-]{1,63}\.[a-z\.]{2,6})$/i", $_SERVER['HTTP_HOST'], $matches);
$bManualSwitch = ($bManualSwitch ? ($bMobile ? $this->_mobile_switch_key : $this->_desktop_switch_key) . ":1" : "");
$sRequestUrl = str_replace("{$this->_mobile_switch_key}:1", '', $_SERVER['REQUEST_URI']) . "/{$bManualSwitch}";
$sRequestUrl = preg_replace('/\/+/', '/', $sRequestUrl);
if($bMobile){
return "http{$this->_sslS}://{$this->_mobile_key}.{$matches['domain']}{$sRequestUrl}";
}else{
return "http{$this->_sslS}://{$this->_base_key}.{$matches['domain']}{$sRequestUrl}";
}
}
/**
* Function to create current possition full URL
*
* @author Mareks Keišs <mareks.keiss@brsystems.lv>
* @category Module
* @return string URL
*/
public function getDomainUrl(){
return "http{$this->_sslS}://" . $_SERVER['HTTP_HOST'];
}
public function getUrl($param = ''){
if(!$param){
return "http{$this->_sslS}://" . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
}else{
$add = $param;
if(is_array($param)){
$add = http_build_query($param);
}
if($add){
if(count($chunks = explode('?', $_SERVER['REQUEST_URI']))>1){
return "http{$this->_sslS}://" . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] . '?' . $chunks[1] . $add;
}else{
return "http{$this->_sslS}://" . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] . '?' . $add;
}
}else{
return "http{$this->_sslS}://" . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
}
}
}
/**
* Function to get base uri from SERVER REQUEST_URI
*
* @author Mareks Keišs <mareks.keiss@brsystems.lv>
* @category Module
* @return string URL
*/
public static function getBaseUrl(){
if($url = $_SERVER['REQUEST_URI']){
$chunks = parse_url($url);
return $chunks['path'];
}
}
/**
* Function to reformat urls based on site settings - remove index page, slashes added / removed if needed
*
* @author Mareks Keiss <keiss.mareks@gmail.com>
* @category Url class
* @param null|string $url - url to format
* @param bool $base - return url in base structure
* @return string - url to be used
*/
public function rmSlashesIndex(?string $url, bool $base = false): string
{
// Check if slash at the end needed & add if necessary
if (!$base) {
if (substr($url, -1) == '/') {
if (!$this->_endSlash) {
$url = substr($url, 0, strlen($url) - 1);
}
} else {
if ($this->_endSlash) {
$url .= '/';
}
}
}
// Remove index page
$len = ($this->_endSlash ? 7 : 6);
if (substr($url, 0, $len) == ($len == 7 ? '/index/' : '/index')) {
$url = substr($url, $len);
}
if (!$url) {
return '/';
}
return $url;
}
}