<?php

// Basic includes
require_once('ESFconfig.php');
require_once('ESFdb_functions.php');
require_once('ESFhelper_functions.php');
require_once('ESFhandler_functions.php');
require_once('ESFcheckout_functions.php');
require_once('ESFio_functions.php');
require_once('ESFecom_shared.php');
require_once('ESFzzz.php');

// phplib includes
require_once('CALdb_functions.php');
require_once('CALhelper_functions.php');
require_once('CALio_functions.php');
require_once('CALstore_functions.php');
require_once('CALecom_functions.php');

require_once('ESFarrays.php');

$myself	    = 'index.php';

// Initialization of some variables used in script, those SHOULD NOT be changed here, those are default values!
//
$maintenance	  = false;	   // Used to signal to script that system is in maintenance mode. Set later automatically
$log_user	  = false;


$act_url	  = false;	   // Contains Action URL returned by displatcher, this is used for URL shortcut display on the page
$page_bootstrap	  = false;	   // Contains Page JS bootstrap (OnLoad) code returned by displatcher
$page_includes	  = false;	   // Contains Page includes returned by displatcher

$track_data	  = false;	   // Contrains a tracking cookie row from database
$session_data	  = false;	   // Contrains a session cookie row from database
$redirect_data	  = false;	   // Contrains a redirect row from database
$agent_id_session = false;	   // Contrains a Agent ID of the CURRENT SESSION
$agent_id_tag	  = false;	   // Contrains a Agent ID of the TRACKING cookie
$agent_id_bind	  = false;	   // Contrains a Agent ID of the parent agent, set only when user is logged on

// Globals, DO NOT delete even if you do not see them in this script.
//
$sqllog		  = false;	    // Log of SQL Statements, written to by query commands
$sqlcount	  = 0;		    // Count of SQL Statements, written to by query commands
$runtime_data	  = array();	    // Used to pass around messages and data structures between functions
$runtime_data['fe'] = true;	    // This flag is needed to make sure that URL generator does right thing

// Timestamps used for debug, in particular SQL Trace
//
$exec_start_time  = microtime(true);
$exec_stamp_time  = $exec_start_time;

// Hardcode some headers for PCI compliance
header("X-Frame-Options: SAMEORIGIN");
header("X-XSS-Protection: 1");
header("X-Content-Type-Options: nosniff");
header("Content-Security-Policy: default-src 'self' 'unsafe-eval' 'unsafe-inline' *.swissgal.com *.codeangels.com assets.pinterest.com");
header("Strict-Transport-Security: max-age=31536000; includeSubDomains");

// Request URI, needed later for URL rewriting:
if ($_SERVER && array_key_exists('REQUEST_URI', $_SERVER) && $_SERVER['REQUEST_URI']) {
      $request_uri = $_SERVER['REQUEST_URI'];
} else {
      $request_uri = false;
}

// Check if system is in maintenance mode:
//
if (file_exists($config['fs_maintenance_flag'])) {
      $maintenance = true;
}

// If system is in maintenance and IP is not private = Show maintenance screen, otherwise proceed.
//
if ($maintenance && !preg_match('/^192.168/', $_SERVER['REMOTE_ADDR'])) {
      $sr = array ('SITE_TITLE' => $config['site_title'], 'RETURN_MESSAGE' => file_get_contents($config['fs_maintenance_flag']));
      print CALrender_page(false, 'store_maintenance_screen.html', $sr, 'disk', $config['default_language']);
      exit;
}

// Open DB Connection
//
$ds = CALdb_conn($databases['main']['hostname'],$databases['main']['port'],$databases['main']['ruser'],$databases['main']['rpass'],$databases['main']['database']);

// If fault, throw error and exit
//
if (!$ds) {
      $sr = array ('SITE_TITLE' => $config['site_title']);
      // TODO: Add mail alert here
      print CALrender_page(false, 'error_fatal_screen.html', $sr, 'disk', $config['default_language']);
      exit;
}

// Load Config
//
ESFmake_config($ds);

// HTTP Redirect hook:
//

if ((array_key_exists('act', $_GET) && $_GET['act'] == 'redirect') && (array_key_exists('obj', $_GET) && $_GET['obj']) && (array_key_exists('opt', $_GET) && $_GET['opt'])) {
      $redirect = CALdb_get_table_row($ds, 'http_redirects', array('web_id', 'deleted'), array($_GET['obj'], null));
      if ($redirect && $redirect['url']) {
	    if ($_GET['opt'] === 'rdr' && !$redirect['typedef']) {
		  if (strpos(strtolower($redirect['url']), $config['urls.system.storefront.tdl'])) {
			if (strpos($redirect['url'], '?')) {
			      $redirect['url'] .= '&rdr=' . urlencode($_GET['obj']);
			} elseif (strpos($redirect['url'], $config['app'])) {
			      $redirect['url'] .= '?rdr=' . urlencode($_GET['obj']);
			} else {
			      $redirect['url'] .= '/R' . $config['store.options.seo.urls.separator'] . urlencode($_GET['obj']);
			}
		  }

		  CALdb_close($ds);
		  header("HTTP/1.1 301 Moved Permanently");
		  header("Location: " . $redirect['url']);
		  exit;
	    } elseif ($_GET['opt'] === 'do' && strpos(strtolower($redirect['url']), $config['urls.system.storefront.tdl'])) {
		  $_GET['rdr'] = $_GET['obj'];
		  $a1 =  parse_url($redirect['url']);
		  if ($a1 && array_key_exists('path', $a1)) {
			$request_uri = $a1['path'];
		  }
		  
		  $a1 = false;
		  $a1['invoked_date'] 	= CALdb_esquote_string(date("Y-m-d G:i:s"));
		  $sql = CALdb_gen_simple_sql($ds, 'http_redirects', $a1, 'WEB_ID = ' . CALdb_esquote_string($_GET['obj']), 'update');
		  CALdb_wquery($sql);
	    } else {
		  CALlogger($ds, 2,4, $myself, 'Attept to invoke non working redirect: \'' . $_GET['obj'] . '\'', false, $log_user);
		  header("HTTP/1.1 301 Moved Permanently");
		  header("Location: " . $config['urls.system.storefront.root']);
		  exit;
	    }
      } else {
	    CALlogger($ds, 2,4, $myself, 'Attept to invoke non existing redirect: \'' . $_GET['obj'] . '\'', false, $log_user);
	    header("HTTP/1.1 301 Moved Permanently");
	    header("Location: " . $config['urls.system.storefront.root']);
	    exit;
      }
}

// URL Generator hook:
//
if ((array_key_exists('act', $_GET) && $_GET['act'] == 'mkurl') && (array_key_exists('lobj', $_GET) && $_GET['lobj'])) {
      $url		= false;
      $agent_id		= false;
      $description	= false;
      $data = CALdecrypt_string($_GET['lobj'], $config['store.values.mkurl.password'], true);
      
      if (CALis_serialized($data)) {
	    $data	= CALunserialize($data);
	    $url	= $data['url'];
	    $agent_id	= $data['agent_id'];
	    $description= $data['description'];
	    $type	= $data['type'];
      } else {
	    $url	= $data;
	    $agent_id	= false;
	    $description= false;
	    $type	= 'go';
      }
      
      if (preg_match('/^[http|ftp]/', $url)) {
	    print $config['urls.system.storefront.root'] . "/$type/" . CALdb_http_redirect($ds, $url, true, false, $description, $agent_id, true, false);
      } else {
	   CALdrop_http_error(400);
      }
      exit;
}

$config['db_table_fields']	    =  CALdb_gen_db_fields_array($ds);
$nls_strings			    =  CALdb_gen_nls_strings_array($ds);

// Pre Parser...
//
// 
$getvars = $_GET;

if ($request_uri) {
      // Is that a query at all?
      //
      if (preg_match("/^\/app\/.+$/", $request_uri)) {
	    // OK, now extract the encoded part!
	    //
	    $vars = false;
	    if (preg_match("/^\/app\/(.+)\/index.xbin.+$/", $request_uri, $matches)) {
		  $vars = $matches[1];
	    } elseif (preg_match("/^\/app\/(.+)$/", $request_uri, $matches)) {
		  $vars = $matches[1];
	    }
	    if ($vars) {
		  $vars = explode('/', $vars);

		  // Verify and wipe non alpha numeric
		  //
		  foreach($vars as $idx => $value) {
			if (CALcheck_system_id($value)) {
			      $vars[$idx] = false;
			}
		  }
		  
		  // Write out stuff into the getvars...
		  //
		  
		  // Extract the search fields
		  //
		  $a1 = false;
		  foreach ($vars as $var) {
			$done = false;
			$values = explode($config['store.options.seo.urls.separator'], $var);
			if (sizeof($values) > 1) {
			      $piece      = array_shift($values);
			      $piece_mode = substr($piece, 0, 1);
			      $piece_id   = substr($piece, 1);
			      
			      if ($piece_mode === 'L' || $piece_mode === 'M') {
				    if (!preg_match('/^\d+$/', $piece_id)) {
					  if ($piece_mode === 'L') {
						$piece_id = CALdb_get_table_field($ds, 'stock_lists', 'sys_id', $piece_id, 'list_id', false);
					  } elseif ($piece_mode === 'M') {
						$piece_id = CALdb_get_table_field($ds, 'meta_searches', 'sys_id', $piece_id, 'search_id', false);
					  }
				    }
					  
				    if ($piece_id) {
					  if ($piece_mode === 'L') {
						$hash   = "s_l_$piece_id";
					  } elseif ($piece_mode === 'M') {
						$hash   = "s_ms_$piece_id";
					  }

					  $elements = array();
					  foreach ($values as $element_id) {
						if (!preg_match('/^\d+$/', $element_id)) {
						      if ($piece_mode === 'L') {
							    $element_id = CALdb_get_table_field($ds, 'stock_list_elements', 'sys_id', $element_id, 'element_id', false);
						      } elseif ($piece_mode === 'M') {
							    $element_id = CALdb_get_table_field($ds, 'meta_search_elements', 'sys_id', $element_id, 'element_id', false);
						      }
						}
						if ($element_id) {
						      $elements[] = $element_id;
						}
					  }
					  
					  if ($elements) {
						$getvars[$hash] = $elements;
					  }
				    }
				    $done = true;
			      } elseif ($piece === 'R') {
				    if (array_key_exists(0, $values)) {
					  $getvars['rdr'] = $values[0];
				    }
				    $done = true;
			      }
			}
			
			if (!$done) {
			      $a1[] = $var;
			}
		  }
		  $vars = $a1;
		  
		  // Common stuff
		  // Region
		  //
		  if (array_key_exists(0, $vars) && $vars[0]) {
			$getvars['region'] = $vars[0];
		  }
		  
		  // Language
		  //
		  if (array_key_exists(1, $vars) && $vars[1]) {
			$getvars['lang'] = CALdb_get_table_field($ds, 'languages', 'sys_id', $vars[1], 'lang_id', false);
		  }
		  
		  // Screen
		  //
		  $screen = false;
		  if (array_key_exists(2, $vars) && $vars[2]) {
			$screen = $vars[2];
			$getvars['scr'] = $screen;
		  }
		  
		  // Now, sceen specifics
		  //
		  if ($screen === 'catalog') {
			// Category
			//
			if (array_key_exists(3, $vars) && $vars[3]) {
			      $getvars['s_cat'] = CALdb_get_table_field($ds, 'shop_categories', 'sys_id', $vars[3], 'category_id', false);
			}
			
			// Page
			//
			if (array_key_exists(4, $vars) && $vars[4]) {
			      $getvars['pg'] = $vars[4];
			}
		  } elseif ($screen === 'style') {
			// Item ID
			//
			if (array_key_exists(3, $vars) && $vars[3]) {
			      $getvars['iid'] = $vars[3];
			}
			
			// Tab
			//
			if (array_key_exists(4, $vars) && $vars[4]) {
			      $getvars['tab'] = $vars[4];
			}
		  } elseif ($screen === 'text') {
			// ACT
			//
			if (array_key_exists(3, $vars) && $vars[3]) {
			      $getvars['act'] = $vars[3];
			}
			
			// Object
			//
			if (array_key_exists(4, $vars) && $vars[4]) {
			      $getvars['obj'] = $vars[4];
			}
			
		  } elseif ($screen === 'account') {
			// Tab
			//
			if (array_key_exists(3, $vars) && $vars[3]) {
			      $getvars['tab'] = $vars[3];
			}
		  }
	    }
      }
}

// Secure web input and place it into vars
//
$getvars    = ESFsecure_web_input($ds, $getvars, $config['secv_get']);
$postvars   = ESFsecure_web_input($ds, $_POST, $config['secv_post']);
$cookievars = ESFsecure_web_input($ds, $_COOKIE, $config['secv_cookie']);

// This next step is needed for Saferpay 3DS callback functionality. The information must be passed by security functions.
//
if (
array_key_exists('scr', $getvars)
	&& $getvars['scr'] == 'checkout'
	&& array_key_exists('sact', $getvars)
	&& $getvars['sact'] == 'ptc') {
      $getvars['raw'] 		= $_GET;
}

// Autodetect region, if enabled and region is not set
//
if (!array_key_exists($cookievars['ecom_fe_reg'], $config['country_regions']) && !array_key_exists($getvars['region'], $config['country_regions']) && $config['store.options.autodetect.region']) {
      $getvars['sobj'] = 'region';
      $getvars['conf'] = 'init';
      $getvars['sact'] = 'sc';
      $v1 = CALgeoip(false, $_SERVER['REMOTE_ADDR']);
      if ($v1 && array_key_exists($v1['country_iso'], $config['country_regions_map'])) {
	    $getvars['sopt'] = strtolower($config['country_regions_map'][$v1['country_iso']]);
      } else {
	    $getvars['sopt'] = 'int';
      }
}

// Do some additional, indepth verification of certain variables which arrived to us via Getvars.
//
// Generate 'allowed' arrays used later to verify contents of the cookies and getvars
//
$allowed_languages 		= array();
$default_language		= false;
$rows = CALdb_get_table_rows($ds, 'languages', 'active', 1, false);
if ($rows) {
      foreach ($rows as $row) {
	    $allowed_languages[] = $row['lang_id'];
	    if ($row['base']) {
		  $default_language = $row['lang_id'];
	    }
      }
}

$allowed_currencies 	= array();
$default_currency		= false;
$rows = CALdb_get_table_rows($ds, 'currencies', 'active', 1, false);
if ($rows) {
      foreach ($rows as $row) {
	    $allowed_currencies[] = $row['currency_id'];
	    if ($row['base']) {
		  $default_currency = $row['currency_id'];
	    }
      }
}

$allowed_unit_systems 	= array(1,2);
$allowed_icon_sizes 	= array(1,2,3);

if (!in_array($config['store.values.default.language'],$allowed_languages)) {
      if ($default_language) {
	    $config['store.values.default.language'] = $default_language;
	    CALlogger($ds, 2,4, $myself, 'Store Default language does not match any active languages! Fallback to languages definition!', false, $log_user);
      } else {
	    CALlogger($ds, 2,0, $myself, 'Could not discover store default language!', false, $log_user);
	    $sr = array ('SITE_TITLE' => $config['site_title']);
	    print CALrender_page(false, 'error_fatal_screen.html', $sr, 'disk', $config['default_language']);
	    exit;
      }
}

if (!in_array($config['store.values.default.currency'],$allowed_currencies)) {
      if ($default_currency) {
	    $config['store.values.default.currency'] = $default_currency;
	    CALlogger($ds, 2,4, $myself, 'Store Default currency does not match any active currency! Fallback to currencies definition!', false, $log_user);
      } else {
	    CALlogger($ds, 2,0, $myself, 'Could not discover store default currency!', false, $log_user);
	    $sr = array ('SITE_TITLE' => $config['site_title']);
	    print CALrender_page(false, 'error_fatal_screen.html', $sr, 'disk', $config['default_language']);
	    exit;
      }
}

// Handle cookie set requests 
//
if (array_key_exists('sact', $getvars) && $getvars['sact'] === 'sc') {
      if (array_key_exists('sobj', $getvars) && $getvars['sobj'] === 'region' && array_key_exists('sopt', $getvars) && array_key_exists($getvars['sopt'], $config['country_regions'])) {
	    ESFcookie_cook('ecom_fe_reg', $getvars['sopt'], false, false, false);
	    $cookievars['ecom_fe_reg']	  = $getvars['sopt'];
	    $getvars['region']		  = $getvars['sopt'];
	    if (array_key_exists('conf', $getvars) && $getvars['conf'] === 'init') {
		  // Force variables
		  // Currency
		  $cookievars['ecom_fe_cur']	= $config['country_regions'][$getvars['sopt']]['cur'];
		  $getvars['cur']		= $cookievars['ecom_fe_cur'];
		  ESFcookie_cook('ecom_fe_cur', $cookievars['ecom_fe_cur'], false, false, false);
		  
		  // Units System
		  $cookievars['ecom_fe_usys']	= $config['country_regions'][$getvars['sopt']]['usys'];
		  ESFcookie_cook('ecom_fe_usys', $cookievars['ecom_fe_usys'], false, false, false);

		  // Language
		  $cookievars['ecom_fe_lang']	= $config['country_regions'][$getvars['sopt']]['lang'];
		  $getvars['lang']		= $cookievars['ecom_fe_lang'];
		  ESFcookie_cook('ecom_fe_lang', $cookievars['ecom_fe_lang'], false, false, false);
	    }
      } elseif (array_key_exists('sobj', $getvars) && $getvars['sobj'] == 'lang' && array_key_exists('sopt', $getvars) && in_array($getvars['sopt'], $allowed_languages)) {
	    ESFcookie_cook('ecom_fe_lang', $getvars['sopt'], false, false, false);
	    $cookievars['ecom_fe_lang'] = $getvars['sopt'];
	    $getvars['lang'] = substr($getvars['sopt'],0,3);
      } elseif (array_key_exists('sobj', $getvars) && $getvars['sobj'] == 'cur' && array_key_exists('sopt', $getvars) && in_array($getvars['sopt'], $allowed_currencies)) {
	    ESFcookie_cook('ecom_fe_cur', $getvars['sopt'], false, false, false);
	    $cookievars['ecom_fe_cur'] = intval($getvars['sopt']);
      } elseif (array_key_exists('sobj', $getvars) && $getvars['sobj'] == 'usys' && array_key_exists('sopt', $getvars) && in_array($getvars['sopt'], $allowed_unit_systems)) {
	    ESFcookie_cook('ecom_fe_usys', $getvars['sopt'], false, false, false);
	    $cookievars['ecom_fe_usys'] = intval($getvars['sopt']);
      } elseif (array_key_exists('sobj', $getvars) && $getvars['sobj'] == 'isz' && array_key_exists('sopt', $getvars) && in_array($getvars['sopt'], $allowed_icon_sizes)) {
	    ESFcookie_cook('ecom_fe_isz', $getvars['sopt'], false, false, false);
	    $cookievars['ecom_fe_isz'] = intval($getvars['sopt']);
      } elseif (array_key_exists('sobj', $getvars) && $getvars['sobj'] == 'rpp' && array_key_exists('sopt', $getvars) && $getvars['sopt'] && is_int($getvars['sopt'])) {
	    ESFcookie_cook('ecom_fe_rpp', $getvars['sopt'], false, false, false);
	    $cookievars['ecom_fe_rpp'] = intval($getvars['sopt']);
      }
	  
	  $cookievars = ESFsecure_web_input($ds, $_COOKIE, $config['secv_cookie']);
}
// Check getvars and WIPE them if they do not match
//
if ($getvars['lang'] && !in_array($getvars['lang'],$allowed_languages)) {
      $getvars['lang'] = '';
}

if ($getvars['region'] && !array_key_exists($getvars['region'], $config['country_regions'])) {
      $getvars['region'] = '';
}

// Check cookies
if (!in_array($cookievars['ecom_fe_lang'],$allowed_languages)) {
      // If getvars has some content: Set to it, otherwise set to default
      if ($getvars['lang']) {
	    $cookievars['ecom_fe_lang'] = $getvars['lang'];
      } else {
	    $cookievars['ecom_fe_lang'] = $config['store.values.default.language'];
      }
      ESFcookie_cook('ecom_fe_lang', $cookievars['ecom_fe_lang'], false, false, false);
}

if (!in_array($cookievars['ecom_fe_cur'],$allowed_currencies)) {
      $cookievars['ecom_fe_cur'] = $config['store.values.default.currency'];
      ESFcookie_cook('ecom_fe_cur', $cookievars['ecom_fe_cur'], false, false, false);
}

if (!array_key_exists('ecom_fe_usys', $cookievars) || !in_array($cookievars['ecom_fe_usys'],$allowed_unit_systems)) {
      $cookievars['ecom_fe_usys'] = $config['store.values.default.unit_system'];
      ESFcookie_cook('ecom_fe_usys', $cookievars['ecom_fe_usys'], false, false, false);
}

if (!array_key_exists('ecom_fe_isz', $cookievars) || !in_array($cookievars['ecom_fe_isz'],$allowed_icon_sizes)) {
      $cookievars['ecom_fe_isz'] = $config['store.values.graphics.html.icon.default'];
      ESFcookie_cook('ecom_fe_isz', $cookievars['ecom_fe_isz'], false, false, false);
}

if (!array_key_exists('ecom_fe_rpp', $cookievars) || !$cookievars['ecom_fe_rpp'] || !is_int($cookievars['ecom_fe_rpp'])) {
      $cookievars['ecom_fe_rpp'] = $config['store.values.default.paginator.rpp'];
      ESFcookie_cook('ecom_fe_rpp', $cookievars['ecom_fe_rpp'], false, false, false);
}

if (!array_key_exists('ecom_fe_reg', $cookievars) || !array_key_exists($cookievars['ecom_fe_reg'], $config['country_regions'])) {
      // If getvars has some content: Set to it, otherwise do nothing (Display selection later)
      if ($getvars['region']) {
	    $cookievars['ecom_fe_reg'] = $getvars['region'];
      }
      ESFcookie_cook('ecom_fe_reg', $cookievars['ecom_fe_reg'], false, false, false);
}

// Verify that both session_id and track_id cookies are valid if present.... if not: Someone is trying to inject some shit, kill the vars!
//
if (array_key_exists('ecom_fe_crt', $cookievars)) {
      $track_data = CALdb_get_table_row($ds, 'log_tracker', 'web_id', $cookievars['ecom_fe_crt']);
      if (!$track_data) {
	    CALlogger($ds, 2, 2, $myself, 'Invalid track ID detected. Possibly forged cookie.', $cookievars, $log_user);
	    unset($cookievars['ecom_fe_crt']);
      }
}

if (array_key_exists('ecom_fe_id', $cookievars)) {
      $session_data = CALdb_get_table_row($ds, 'shop_sessions', 'web_id', $cookievars['ecom_fe_id'], 'content', false);
      if (!$session_data) {
	    CALlogger($ds, 2, 2, $myself, 'Invalid Session ID detected. Possibly forged cookie.', $cookievars, $log_user);
	    unset($cookievars['ecom_fe_id']);
      } elseif ($session_data['expired']) {
	    $session_data = false;
	    CALlogger($ds, 2, 2, $myself, 'Session is marked as expired.', $cookievars, $log_user);
	    unset($cookievars['ecom_fe_id']);
      }
}

// Load redirect data, if present.
//
if (array_key_exists('rdr', $getvars) && $getvars['rdr']) {
      $redirect_data = CALdb_get_table_row($ds, 'http_redirects', 'web_id', $getvars['rdr']);
      $runtime_data['tracking']['redirect_id'] = $redirect_data['redirect_id'];
} else {
      $runtime_data['tracking']['redirect_id'] = false;
}


// Set getvars to cookie values, if those are not set yet
//
if (!in_array($getvars['lang'],$allowed_languages)) {
      $getvars['lang'] = $cookievars['ecom_fe_lang'];
}
if (!array_key_exists($getvars['region'], $config['country_regions'])) {
      $getvars['region'] = $cookievars['ecom_fe_reg'];
}

// Tracking Cookie 
//
if (!$track_data) {
      $track_web_id = CALdb_uranstring($ds, 80, 'log_tracker', 'web_id');
      ESFcookie_cook('ecom_fe_crt', $track_web_id, false, false, false);
      $cookievars['ecom_fe_crt'] = $track_web_id;
      
      $a1 = false; 
      $a1['web_id']	      = CALdb_esquote_string($track_web_id);
      $a1['create_date']      = CALdb_esquote_string(date("Y-m-d G:i:s"));
      
      if ($redirect_data && $redirect_data['agent_id']) {
	    //
	    // AGENT BINDING -> Sticky Tag, we always set it. If it comes into play or not is decided later.
	    //
	    $a1['agent_id'] = $redirect_data['agent_id'];
      }
      
      $sql = CALdb_gen_simple_sql($ds, 'log_tracker', $a1, false, 'insert');
      CALdb_query($ds, $sql);
      CALlogger($ds, 2, 5, $myself, 'New Tracking Session', false, array('track_web_id' => $track_web_id));
      $runtime_data['tracking']['virgin'] = true;
      $track_data = CALdb_get_table_row($ds, 'log_tracker', 'web_id', $track_web_id);
} else {
      $runtime_data['tracking']['virgin'] = false;
      $track_data = CALdb_get_table_row($ds, 'log_tracker', 'web_id', $cookievars['ecom_fe_crt']);
}

// TRACK DATA - Initialize the array, set the track ID, this is done only once and here.
//
$runtime_data['tracking']['track_id']		= $track_data['track_id'];
$runtime_data['tracking']['session_id']		= false;
$runtime_data['tracking']['agent_id_session']   = false;
$runtime_data['tracking']['agent_id_tag']	= false;
$runtime_data['tracking']['agent_id_bind']      = false;
$runtime_data['tracking']['user_id']		= false;
$runtime_data['tracking']['user_name']		= 'guest';

// Now, that we have our tracking row we can safely set the TAG based agent_id_tag:
//
$agent_id_tag = $track_data['agent_id'];

// Also attempt to set REDIRECT based agent_id_session
//
if ($redirect_data) {
      $agent_id_session	      = $redirect_data['agent_id'];
}

// Session start
//
if (!$session_data) {
      $session = false;
      
      $sql = "BEGIN WORK;\n";
      $session_web_id = CALdb_uranstring($ds, 80, 'shop_sessions', 'web_id');
      ESFcookie_cook('ecom_fe_id', $session_web_id, false, false, false);
      
      $sessionvars				      = array('session_web_id' => $session_web_id, 'session_web_ids' => false);
      $sessionvars['rid']			      = CALranstring(60);
      $sessionvars['region']			      = $cookievars['ecom_fe_reg'];
      $sessionvars['remote_addr']		      = $_SERVER['REMOTE_ADDR'];
      
      // TRACK DATA - Set the session agent, within session itself this is needed because we only 
      // get information about the redirect clicked once when it happens and must thus store it 
      // somewhere for later clicks
      //
      $sessionvars['tracking']['agent_id_session']    = $agent_id_session;
      $sessionvars['tracking']['track_id']	      = $track_data['track_id'];
      
      $a1		      = false;
      $a1['web_id']	      = CALdb_esquote_string($session_web_id);
      $a1['content']	      = CALdb_esquote_string(CALserialize($sessionvars));
      $a1['created_date']     = CALdb_esquote_string(date("Y-m-d G:i:s"));
      $sql		      .= CALdb_gen_simple_sql($ds, 'shop_sessions', $a1, false, 'insert');

      // Check if there is a tracking ID and it is valid bind the session to the track ID:
      //
      if ($track_data) {
	    $a1		      = false;
	    $a1['session_id'] = "(SELECT CURRVAL('shop_sessions_session_id_seq'))";
	    $a1['track_id']   = $track_data['track_id'];
	    $sql	     .= CALdb_gen_simple_sql($ds, 'log_tracker_shop_sessions', $a1, false, 'insert');
      } else {
	    CALlogger($ds, 2, 3, $myself, 'New session without tracking ID', array('session_web_id' => $session_web_id), false);
      }
      $sql		     .= "COMMIT WORK;\n";
      CALdb_query($ds, $sql);
      $session_data = CALdb_get_table_row($ds, 'shop_sessions', 'web_id', $session_web_id);
      
      // TRACK DATA
      //
      $runtime_data['tracking']['session_id']	      = $session_data['session_id'];
      $runtime_data['tracking']['agent_id_session']   = $agent_id_session;
      $runtime_data['tracking']['agent_id_tag']	      = $agent_id_tag;
      
      $log_user = ESFget_log_user();
      
      CALlogger($ds, 2, 5, $myself, 'New session', false, $log_user);
} else {
      // Check if there is a link between tracker and session cookies, if not, establish that link.
      //
      if (!CAldb_get_table_row($ds,'log_tracker_shop_sessions', array('track_id', 'session_id'), array($track_data['track_id'], $session_data['session_id']))){
	    $a1 = false;
	    $a1['session_id']	    = $session_data['session_id'];
	    $a1['track_id']	    = $track_data['track_id'];
	    $sql = CALdb_gen_simple_sql($ds, 'log_tracker_shop_sessions', $a1, false, 'insert');

	    CALdb_query($ds, $sql);
	    CALlogger($ds, 2, 5, $myself, 'New Tracking -> Session Link', false, array('track_id' => $track_data['track_id'], 'session_id' => $session_data['session_id']));
      }

      // Parse and load session data
      //
      $sessionvars = CALunserialize($session_data['content']);
      
      // TRACK DATA - if session agent ID is already set, then this was a redirect call and we will override 
      // information in the session with it. If not - we will do vice versa and set the variable to session value
      //
      if ($agent_id_session) {
	    $sessionvars['tracking']['agent_id_session'] = $agent_id_session;
      } else {
	    $agent_id_session = $sessionvars['tracking']['agent_id_session'];
      }
      
      // TRACK DATA
      //
      $runtime_data['tracking']['session_id']	      = $session_data['session_id'];
      $runtime_data['tracking']['agent_id_session']   = $agent_id_session;
      $runtime_data['tracking']['agent_id_tag']	      = $agent_id_tag;

      // If auth block exists
      //
      if (array_key_exists('authinfo', $sessionvars)) {
	    // Wipe the secure flag...
	    // This is required because this could be passed over to us from previous call / session storage
	    // We, on another hand must ALWAYS perform check in order to see if this session can be concidered 
	    // secure. This is done couple of lines later.
	    //
	    $sessionvars['authinfo']['secure'] = 0;
	    
	    // Extract username / ID information for the log_user as well as his bindings
	    //
	    $login			  = CALdb_get_table_row($ds, 'customer_logins', 'web_id',$sessionvars['authinfo']['login'], false);
	    
	    // TRACK DATA - update information for authenticated user:
	    //
	    $runtime_data['tracking']['agent_id_bind']	    = CALdb_get_table_field($ds, 'agents_tree', 'child', $login['customer_id'], 'agent', false);
	    $runtime_data['tracking']['user_id']	    = $login['login_id'];
	    $runtime_data['tracking']['user_name']	    = $login['login'];
	    
	    // Check if this user is an agent and set approproate flags:
	    //
	    if (CAldb_get_table_rows($ds, 'customer_flags', array('customer_id', 'flag', 'value'), array($login['customer_id'], 5, 1), false)) {
		  $sessionvars['authinfo']['agent'] = 1;
	    } else {
		  $sessionvars['authinfo']['agent'] = 0;
	    }
      }

      // Set LOG User
      $log_user = ESFget_log_user();

      // If we are on secure link, we might check for ecom_fe_ids and it's match...
      if (array_key_exists('authinfo', $sessionvars) && array_key_exists('HTTPS', $_SERVER) && $_SERVER['HTTPS'] == 'on') {

	    // Is there a ecom_fe_ids cookie and does it contain something?
	    if (array_key_exists('ecom_fe_ids', $cookievars) && $cookievars['ecom_fe_ids']) {
		  // Does it match the info in $session?
		  if ($cookievars['ecom_fe_ids'] == $session_data['web_ids']) {
			$sessionvars['authinfo']['secure'] = 1;
		  }
	    }

	    // If the step above did not produce secure flag then something is very wrong, because the cookie infos MUST match!
	    //
	    // We KILL authinfo! Because something is very wrong! We also log it!
	    // This block should also more or less take care about all further security checks. But we do check for secure flag anyway...
	    //
	    if (!$sessionvars['authinfo']['secure']) {
		  unset($sessionvars['authinfo']);
		  unset($sessionvars['checkout_id']);
		  ESFcookie_cook('ecom_fe_ids', "", false, false, true);
		  $sessionvars['session_web_ids'] 	= false;
		  $a1 = false;
		  $a1['web_ids'] = null;
		  $sql = CALdb_gen_simple_sql($ds, 'shop_sessions', $a1, ' WEB_ID = ' . CALdb_esquote_string($sessionvars['session_web_id']), 'update');
		  CALdb_query($ds, $sql);
		  CALlogger($ds, 2, 4, $myself, 'Session contains authinfo but secure verification failed!: ' . $session_data['session_web_ids'], false, $log_user);
		  
		  // TRACK DATA - update information and remove authenticated user:
		  //
		  $runtime_data['tracking']['agent_id_bind']	  = false;
		  $runtime_data['tracking']['user_id']		  = false;
		  $runtime_data['tracking']['user_name']	  = 'guest';
	    }
      }

      if (array_key_exists('cart', $sessionvars) && $sessionvars['cart']) {
	    $sessionvars['cart'] = CALparse_shop_cart_data($ds, intval($sessionvars['cart']));
      }

      // Decode time when session was accessed:
      $v1 = CALdb_decode_date($session_data['accessed_date'], false);
      $v1 = $v1['timestamp'];

      // Check if the session is older then max allowed session age OR IP in session header does not match to actual remote IP
      //
      if ((time() - $v1) >= $config['store.values.security.sessions.expiration.session'] || ($config['store.values.security.sessions.bind.ip'] && $sessionvars['remote_addr'] != $_SERVER['REMOTE_ADDR'])) {
	    // TOTAL WIPE, basically same as new initialization!
	    if ($config['store.values.security.sessions.bind.ip'] && $sessionvars['remote_addr'] != $_SERVER['REMOTE_ADDR']) {
		  CALlogger($ds, 2, 4, $myself, 'Session IP changed from ' . $sessionvars['remote_addr'] . ' to ' . $_SERVER['REMOTE_ADDR'], $sessionvars, $log_user);
	    }

	    if ((time() - $v1) >= $config['store.values.security.sessions.expiration.session']) {
		  CALlogger($ds, 2, 5, $myself, 'Session expired.', $sessionvars, $log_user);
	    }

	    $v1 = CALdb_uranstring($ds, 80, 'shop_sessions', 'web_id');

	    ESFcookie_cook('ecom_fe_id', $v1, false, false, false);
	    ESFcookie_cook('ecom_fe_ids', "", false, false, true);

	    $sessionvars = array('session_web_id' => $v1, 'session_web_ids' => false);
	    $sessionvars['rid'] = CALranstring(60);
	    $sessionvars['region'] = $cookievars['ecom_fe_reg'];
	    $sessionvars['remote_addr'] = $_SERVER['REMOTE_ADDR'];
	    // TRACK DATA - Similar to what we do above when session is not existing at all.
	    //
	    $sessionvars['tracking']['agent_id_session']    = $agent_id_session;
	    $sessionvars['tracking']['track_id']	    = $track_data['track_id'];
	    
	    $a1 = false;
	    $a1['web_id'] = CALdb_esquote_string($v1);
	    ;
	    $a1['content'] = CALdb_esquote_string(CALserialize($sessionvars));
	    $a1['created_date'] = CALdb_esquote_string(date("Y-m-d G:i:s"));
	    $sql = CALdb_gen_simple_sql($ds, 'shop_sessions', $a1, false, 'insert');
	    CALdb_query($ds, $sql);
	    
	    // TRACK DATA - update information and remove authenticated user:
	    //
	    $runtime_data['tracking']['agent_id_bind']	  = false;
	    $runtime_data['tracking']['user_id']	  = false;
	    $runtime_data['tracking']['user_name']	  = 'guest';
      } elseif ((time() - $v1) >= $config['store.values.security.sessions.expiration.authentication'] && array_key_exists('authinfo', $sessionvars)) {
	    CALlogger($ds, 2, 5, $myself, 'Authentication Expired.', $sessionvars, $log_user);
	    // Destroy authinfo and unlink checkout
	    unset($sessionvars['authinfo']);
	    unset($sessionvars['checkout_id']);

	    // Save the current session as copy, we do not want to overwrite the existing one because of the audit reasons
	    //
	    $v1 = CALdb_uranstring($ds, 80, 'shop_sessions', 'web_id');
	    ESFcookie_cook('ecom_fe_id', $v1, false, false, false);
	    $sessionvars['session_web_id']	= $v1;
	    $sessionvars['session_web_ids'] 	= false;
	    $sessionvars['rid'] 		= CALranstring(60);
	    $sessionvars['region'] = $cookievars['ecom_fe_reg'];
	    $a1 = false;
	    $a1['web_id'] = CALdb_esquote_string($v1);
	    ;
	    $a1['content'] = CALdb_esquote_string(CALserialize($sessionvars));
	    $a1['created_date'] = CALdb_esquote_string(date("Y-m-d G:i:s"));
	    $sql = CALdb_gen_simple_sql($ds, 'shop_sessions', $a1, false, 'insert');
	    CALdb_query($ds, $sql);
	    
	    // TRACK DATA - update information and remove authenticated user:
	    //
	    $runtime_data['tracking']['agent_id_bind']	  = false;
	    $runtime_data['tracking']['user_id']	  = false;
	    $runtime_data['tracking']['user_name']	  = 'guest';
      }
}

//
// Check sizer info, if set:
//
if (array_key_exists('sizer', $sessionvars) && $sessionvars['sizer']) {
      $row = CALdb_get_table_row($ds, 'customer_sizesets', 'web_id', $sessionvars['sizer']['id']);
      if ($row) {
	    if ($row['login_id'] && !array_key_exists('authinfo', $sessionvars)) {
		  CALlogger($ds, 2, 3, $myself, 'Sizer is set in session but it belongs to a user and we are not currently logged on!', $sessionvars['sizer'], $log_user);
		  unset($sessionvars['sizer']);
	    } elseif ($row['login_id'] && array_key_exists('authinfo', $sessionvars)) {
		  if ($row['login_id'] != CALdb_get_table_field($ds, 'customer_logins', 'web_id', $sessionvars['authinfo']['login'], 'login_id', false)) {
			CALlogger($ds, 2, 3, $myself, 'Sizer is set in session but it belongs to a different user!', $sessionvars['sizer'], $log_user);
			unset($sessionvars['sizer']);
		  }
	    }
      } else {
	    CALlogger($ds, 2, 3, $myself, 'Sizer is set in session but does not exist in database!', $sessionvars['sizer'], $log_user);
	    unset($sessionvars['sizer']);
      }
}



$sessionvars['region'] = $cookievars['ecom_fe_reg'];

// Assign a cart to session if it does not exist yet

if (!array_key_exists('cart', $sessionvars) || !$sessionvars['cart']) {
      $sessionvars['cart'] = CALgen_new_cart($ds, 0, false, $sessionvars['session_web_id']);
}

$sr = CALget_standard_store_sr($ds);

if (!array_key_exists('ecom_fe_reg', $cookievars) || !array_key_exists($cookievars['ecom_fe_reg'], $config['country_regions'])) {
      $sr1 	= CALget_standard_store_sr($ds);
      foreach ($config['country_regions'] as $region) {
	    $sr1["URL_" .  $region['id']] = CALgen_url($ds, $config['app'], $getvars, array('sact' => 'sc', 'sobj' => 'region', 'sopt' => $region['id'], 'conf' => 'init'), false, $config['udb']['permit']['switch'], false);
	    
      }
      //$sr1['SWISSURL'] = CALgen_url($ds, $config['app'], $getvars, array('sact' => 'sc', 'sobj' => 'region', 'sopt' => 'CH', 'conf' => 'init'), false, $permited_getvars, false);
      //$sr1['OTHERURL'] = CALgen_url($ds, $config['app'], $getvars, array('sact' => 'sc', 'sobj' => 'region', 'sopt' => 'OTHER'), false, $permited_getvars, false);
      $title 	= CALnls_string($ds, 'Welcome', $getvars['lang']);
      $code 	= CALrender_page($ds, 'shop.screens.location', $sr1, false, $getvars['lang']);
} else {
      $sr['HOMEURL']	= $config['urls.system.storefront.root'] . CALgen_url($ds, $config['app'], $getvars, array('scr' => 'root'), array('s_run' => true, 's_cid' => true), $config['udb']['permit']['naked'], false);
      $sr['TEXTURL']	= $config['urls.system.storefront.root'] . $sr['TEXTURL'];
      

      // BODY
      list($rc, $message, $title, $code, $sessionvars, $act_url, $redirect_url, $page_bootstrap, $page_includes, $root_type) = ESFdispatch_handler($ds, $getvars, $postvars, $cookievars, $sessionvars);

      // HEADER
      $sr['HEADBAR']	= "<A HREF=\"" . $sr['HOMEURL'] . "\">" . CALnls_string($ds, 'Home', $getvars['lang']) . "</A>";
      if (array_key_exists('authinfo', $sessionvars)) {

	    $sr['HEADBAR']    .= " " . $config['store.values.visual.options_bar_separator'] . " ";
	    $url	      = $config['urls.system.storefront.root.ssl'] . CALgen_url($ds, $config['app'], $getvars, array('scr' => 'account'), false, $config['udb']['permit']['naked'], false);
	    $sr['HEADBAR']    .= "<A HREF=\"$url\">" . CALnls_string($ds, 'My account', $getvars['lang']) . "</A>";
	    $sr['HEADBAR']    .= " (" . CALhtml_specialchars(CALdb_get_table_field($ds, 'customers', 'web_id', $sessionvars['authinfo']['customer'], 'name', false)) . ") ";

	    $sr['HEADBAR']    .= " " . $config['store.values.visual.options_bar_separator'] . " ";
	    $url	      = $config['urls.system.storefront.root.ssl'] . CALgen_url($ds, $config['app'], $getvars, array('sact' => 'logoff'), false, $config['udb']['permit']['switch'], false);
	    $sr['HEADBAR']    .= " <A HREF=\"$url\">" . CALnls_string($ds, 'Sign off', $getvars['lang']) . "</A>";
      } else {

	    $sr['HEADBAR']    .= " " . $config['store.values.visual.options_bar_separator'] . " ";
	    $sr['HEADBAR']    .= CALnls_string($ds, 'Not signed on', $getvars['lang']);

	    $sr['HEADBAR']    .= " " . $config['store.values.visual.options_bar_separator'] . " ";
	    $url	      = $config['urls.system.storefront.root.ssl'] . CALgen_url($ds, $config['app'], $getvars, array('scr' => 'signon'), false, $config['udb']['permit']['naked'], false);
	    $sr['HEADBAR']    .= "<A HREF=\"$url\">" . CALnls_string($ds, 'Sign on', $getvars['lang']) . "</A>";

	    $sr['HEADBAR']    .= " " . $config['store.values.visual.options_bar_separator'] . " ";
	    $url	      = $config['urls.system.storefront.root.ssl'] . CALgen_url($ds, $config['app'], $getvars, array('scr' => 'register'), false, $config['udb']['permit']['naked'], false);
	    $sr['HEADBAR']    .= "<A HREF=\"$url\">" . CALnls_string($ds, 'Register', $getvars['lang']) . "</A>";
      }

      list ($v1, $v2, $v3) = ESFrender_cart($ds, $getvars, $sessionvars['cart'], $config['udb']['permit']['naked'], 'mini');
      $sr['CART']	  = $v1;

      // FOOTER
      $sr['REGION']	= ESFgen_region_selector($ds, $getvars, $cookievars, $config['udb']['permit']['switch'], false);
      $sr['POLICIES']	= CALrender_page($ds, 'shop.bits.policies.bar', array('TEXTURL' => $sr['TEXTURL'], 'SEPARATOR' => $config['store.values.visual.options_bar_separator']), false, $getvars['lang']);
}

$sr['SITE_TITLE'] = $config['site_title'];
$sr['CONTENT']  = $code;
$sr['TITLE'] 	= $title;

if ($page_bootstrap) {
      $sr['PAGE_BOOTSTRAP'] 	= "onLoad=\"$page_bootstrap\"";
}


$template = "shop.screens.root.$root_type";

// Implant URL Shortcuts if agent:
if (array_key_exists('authinfo', $sessionvars) && array_key_exists('agent', $sessionvars['authinfo']) && $sessionvars['authinfo']['agent']) {
      if (in_array($getvars['scr'], explode(',',$config['store.values.linker.screens_allowed']))) {
	    $row = CALdb_get_table_row($ds, 'customers', 'web_id', $sessionvars['authinfo']['customer']);
	    
	    /*
	    if ($config['store.options.seo.urls.enabled']) {
		  $url = "$redirect_url/A" . $config['store.options.seo.urls.separator'] . $row['agent_web_id'];
	    } else {
		  $url = "$redirect_url&lid=" . $row['agent_web_id'];
	    }
	     * 
	     */
	    
	    $a1 = array('url' => $redirect_url, 'description' => $title, 'agent_id' => $row['customer_id'], 'type' => 'do');
	    $sr['MKURL']	    = CALgen_url($ds, $config['app'], array(), array('act' => 'mkurl', 'lobj' => urlencode(CALencrypt_string(CALserialize($a1), $config['store.values.mkurl.password'], true))), false, false, false);
	    $sr['LINKER_LAYER']     = CALrender_page($ds, 'shop.bits.linker.layer', $sr, false, $getvars['lang']);
	    $sr['LINKER_TRIGGER']   = CALrender_page($ds, 'shop.bits.linker.script', $sr, false, $getvars['lang']);
	    $sr['LINKER_TRIGGER']  .= CALrender_page($ds, 'shop.bits.linker.trigger', $sr, false, $getvars['lang']);
	    $page_includes[] = 'jquery';
      }
}

// DEEP HEADER
if (in_array($getvars['scr'], explode(',',$config['store.values.deep.header.screens']))) {
      $sr1 = CALget_standard_store_sr($ds);
      $sr1['SIZERURL'] = CALgen_url($ds, $config['app'], $getvars, array('scr' => 'sizer'), false, $config['udb']['permit']['naked'], false);
      $sr1['AVATARURL'] = CALgen_url($ds, $config['app'], $getvars, array('scr' => 'avatar'), false, $config['udb']['permit']['naked'], false);
      $sr1['TEASERURL'] = CALgen_url($ds, $config['app'], $getvars, array('scr' => 'teaser'), false, $config['udb']['permit']['naked'], false);
      $sr['DEEP_HEADER_CELLS'] = CALrender_page($ds, 'shop.bits.deep.header', $sr1, false, $getvars['lang']);
}
      
//shop.bits.deep.header


// Session end
//
if (is_array($sessionvars) && $sessionvars['session_web_id']) {
      if (array_key_exists('cart', $sessionvars)) {
	    $sessionvars['cart'] = $sessionvars['cart']['id'];
      }
      $a1 = false;
      $a1['content'] = CALdb_esquote_string(CALserialize($sessionvars));
      $a1['accessed_date'] = CALdb_esquote_string(date("Y-m-d G:i:s"));
      $sql = CALdb_gen_simple_sql($ds, 'shop_sessions', $a1, ' WEB_ID = ' . CALdb_esquote_string($sessionvars['session_web_id']), 'update');
      CALdb_query($ds, $sql);
}


if ($page_includes) {
      $page_includes = array_unique($page_includes);
      $sr1 = CALget_standard_store_sr($ds);
      
      $sr['PAGE_INCLUDES'] = false;
      foreach ($page_includes as $include) {
	    $sr['PAGE_INCLUDES'] .= CALrender_page($ds, "shop.bits.includes.$include", $sr1, false, $getvars['lang']) . "\n";
      }
}

$debug['elapsed'] = round(microtime(true) - $exec_start_time,2);
if ($config['store.options.debug.in_html']) {
      $sr1		      = false;
      $sr1['GEN_TIMESTAMP']   = CALhtml_specialchars(date("Y-m-d G:i:s"));
      $sr1['GEN_ELAPSED']     = $debug['elapsed'];
      $sr['PAGE_DEBUG']	      = CALrender_page($ds, 'shop.bits.debug', $sr1, false, $config['default_language']);
}

if ($maintenance) {
      $config['system.level'] = 'Maintenance';
}

if ($config['system.level'] != 'Production') {
      $v1 = "<DIV CLASS=\"system_stripe system_stripe_" . $config['system.level'] . "\">";
      
      $v1 .= CALcss($debug['elapsed'] . "sec, $sqlcount db hits", 'system_stripe_timestamp', false) . " &nbsp; &nbsp; ";
      
      for ($i = 0; $i < $config['values.visual.system.display.count']; $i++) {
	    $v1 .= $config['system.level'] . " &nbsp; &nbsp; ";
      }
      $v1 .= CALcss($debug['elapsed'] . "sec, $sqlcount db hits", 'system_stripe_timestamp', false);
      $v1 .= "</DIV>";
      $sr['SYSTEM_STRIPE'] = $v1;
}

$code = CALrender_page($ds, $template, $sr, false, $getvars['lang']);
if (!$code) {
      // WTF? No output!
      $sr = array ('SITE_TITLE' => $config['site_title']);
      // TODO: Add mail alert here
      $code = CALrender_page(false, 'error_fatal_screen.html', $sr, 'disk', $config['default_language']);
}

print $code;

if ($config['store.options.debug.sqllog']) {
      pre_print($sqllog);
}

CALdb_close($ds);

?>