websiteFolder . '/sd_function/config.php'; /** @noinspection PhpIncludeInspection */ require_once $uri->websiteFolder . '/sd_function/classes/Publish_AutoLoader.php'; $webRoot = $uri->websiteFolder; } else { # Database connection layer /** @noinspection PhpIncludeInspection */ require_once 'sd_function/config.php'; /** @noinspection PhpIncludeInspection */ require_once 'sd_function/classes/Publish_AutoLoader.php'; $webRoot = null; } spl_autoload_register( array ( new Publish_AutoLoader( $_COOKIE['debug_autoloader'] || $seo_debug, $webRoot ), 'autoLoad' ) ); # Now that we got the site folder, check whether we should update domain + region $uri->updateRegion($aDomains); ################################################################################################### /** * Class Uri_Handler * IMPORTANT: This class cannot easily be moved from this file. We parse this file and replace some texts before saving it as a new file (with the same name) during publish. * */ class Uri_Handler { /** * Current domain information as provided from MatchDomain check in setDomainInfo() * @var array */ private $domain = array(); /** * List of all current domains as provided from $aDomains (domains.php) * @var array */ private $domains = array(); /** * Region ID, provided from $this->domain * @var int */ private $region = 1; /** * List of all configured web sites in SiteDirect (from domains.php) * @var array */ private $sites = array(); /** * Current site ID (1-infinity). False if not set. * @var bool|int */ private $site = false; // If we have this defaulted to 1, some validation checks fail /** * Directory containing the current site's web content. Used only for including configuration files. * @var string|int */ private $websiteFolder; /** * Directory containing the current site's web content. Used in the script. * Strangely enough, $siteFolder and $webSiteFolder cannot be the same variable. It causes strange errors. * @var string|int */ private $siteFolder; /** * If the website folder cannot be determined we use this to track it. * @var bool */ private $unknownSiteFolder = false; /** * Enable debug (using $_GET["_seo_debug"] 1/0) yes or no. * @var bool */ private $debug = false; /** * Contains all data gathered using debug mode. * @var array */ private $debugStack = array(); /** * Timestamp for debug * @var int */ private $debugTimestamp = 0; /** * Should we redirect to a mobile domain (from a non-mobile domain) * @var bool */ private $redirectToMobileDomain = false; /** * Contains a stripped version of $_SERVER['DOCUMENT_ROOT']. Used for paths. * @var mixed */ private $documentRoot; /** * Contains a stripped version of $_SERVER['REQUEST_URI']. Used for paths. * @var string */ private $requestUrl; /** * Concatenation of $documentRoot and $requestUrl * @var string */ private $requestPath; /** * Variant of $requestPath * @var string */ private $requestRel; /** * Modified version of $_SERVER['SCRIPT_NAME'] * @var bool|string */ private $siteUrl; /** * The web domain has a mobile web site as well. * @var bool */ private $mobileDomain = false; /** * Web page item ID (web_page-s1/123) for start page for the current domain. False upon failure to find a start page. * @var string|bool */ private $startPage; /** * Exploded (explode()) data from $startPage * $aStartPage[0] = web page table (web_page-sN) * $aStartPage[1] = web page id (123) * @var array */ private $aStartPage; /** * Site ID for web page item * @var int */ private $startPageSite; /** * Region ID for web page item * @var int */ private $startPageRegion; public $redirectType; /** * @param array $aDomains List of domains configured for the SiteDirect installation (all web sites) * @param array $aSites List of configured web sites */ function __construct($aDomains, $aSites) { $this->documentRoot = preg_replace("/\/$/", '', $_SERVER['DOCUMENT_ROOT']); # Remove ending slash $this->requestUrl = urldecode(preg_replace('/(.*)\?.*/','$1',$_SERVER['REQUEST_URI'])); $this->requestPath = $this->documentRoot.$this->requestUrl; $this->setDomainInfo($aDomains); $this->setSiteInfo($aSites); $this->websiteFolder = $this->domain["sitename"]; # This is a temporary domain set here. We might have to update it after the autoloader has been registered. if ($this->domain['region']) { $this->region = $this->domain['region']; } $this->initDebug(); } /** * Modified version of function MatchDomain. * @param string $pattern Stored URL from domains.php * @param string $domain From $_SERVER["HTTP_HOST"] * @param bool $exactMatch * @return bool */ private function matchDomain($pattern, $domain, $exactMatch=false) { if ($exactMatch === true) { if ($domain == $pattern) { return true; } return false; } $aMatch = explode("*", $pattern); $match = true; foreach ($aMatch as $index => $subString) { if ($index == 0 && $subString != "") { if (substr($domain, 0, strlen($subString)) != $subString) { $match = false; break; } } elseif ($subString != "") { if (strpos($domain, $subString) === false) { $match = false; break; } } } return $match; } /** * Initializes debug mode */ private function initDebug() { if (isset($_GET["_seo_debug"])) { $this->debug = (bool) $_GET["_seo_debug"]; } if ($this->debug) { $this->setDebugTimeStamp(); } } /** * Sets domain related variables * @param array $aDomains List of domains configured for the SiteDirect installation (all web sites) */ private function setDomainInfo($aDomains) { $exactMatch = false; foreach ($aDomains as $value) { if (!$exactMatch && $value['url'] == $_SERVER['HTTP_HOST']) { $exactMatch = $value; break; } else { $searchFor = '/^' . preg_quote($value['url'], '/') . '$/'; $searchFor = str_replace('\*', '.*', $searchFor); $searchFor = str_replace('\$', '$', $searchFor); if (preg_match($searchFor, $_SERVER['HTTP_HOST'] )) { if (isset($bestMatch)) { if (strlen($value['url']) > strlen($bestMatch['url'])) { $bestMatch = $value; } } else { $bestMatch = $value; } } } } if ($exactMatch) { $aDomain = $exactMatch; } else if (isset($bestMatch)) { $aDomain = $bestMatch; } else if (!isset($aDomain) || !is_array($aDomain)) { $aDomain = array ( 'site' => 1, 'sitename' => "1", 'region' => 1, 'url' => '*', 'website_live' => 0, ); } $this->domain = $aDomain; $this->domains = $aDomains; if ($this->domain["mobile_domain"] === true) { $this->mobileDomain = true; } } /** * Fetches URL rewrites without item type and region * @param int $site Site ID (1-inf) * @param int $region Region ID (1-inf) * @param string $item_type SiteDirect item table (web_page-sn( * @param string $url * @param int $query_domain * @return array|bool|null */ public function getRewriteList($site, $url, $query_domain=0) { $url = DB::escape($url); $url = substr($url, 1); // Removed first slash $query = "SELECT * FROM `seo_rewrites-s{$site}` WHERE url='{$url}' AND domain=$query_domain"; $rs = DB::query($query); $aRewrites = DB::fetch($rs); return $aRewrites; } /* We have multiple domains stored with this name (same domain on multiple regions - which is ok). We do however, need to find the correct region. We do this by looking at the URL and match it to a region. We assume that all matched domains share the same site (reasonable since it is exact matching on domains) */ public function updateRegion($aDomains) { # Get domain info $aDomain = array(); $domainMatchCount = 0; $matchedDomains = array(); foreach ($aDomains as $domain) { if ($this->matchDomain($domain["url"], $_SERVER["HTTP_HOST"], true)) { $aDomain = $domain; $matchedDomains[] = $aDomain; $domainMatchCount++; } } /* We have multiple domains stored with this name (same domain on multiple regions - which is ok). We do however, need to find the correct region. We do this by looking at the URL and match it to a region. We assume that all matched domains share the same site (reasonable since it is exact matching on domains) */ if ($domainMatchCount > 1 && !empty($aDomain)) { $site = $aDomain["site"]; $rewrites = $this->getRewriteList($site, $this->requestUrl); #echo '[rewrites]'.print_r($rewrites, true).""; #echo '[matchedDomains]'.print_r($matchedDomains, true).""; if (is_array($rewrites)) { foreach ($rewrites as $rewrite) { $region = $rewrite["region"]; if ($region != $this->region) { #echo "REGION SWITCH DETECTED"; #var_dump($region, $this->region); # Ok, we have found the correct region. Lets put it to use. foreach ($matchedDomains as $matchedDomain) { if ($matchedDomain["region"] == $region) { # echo "SWITCHING DOMAINS"; # var_dump($this->domain, $matchedDomain); # var_dump($this->region, $region); # Only switch region when we have the matching domain. $this->region = $region; $this->domain = $matchedDomain; return true; } } } } } } return null; } /** * Sets site related variables * @param array $aSites List of configured web sites */ private function setSiteInfo($aSites) { $this->sites = $aSites; ################################################################################################### # If site folders are used(i.e. domain is not pointed to the site folder), figure out which site to use. if (SITE_FOLDERS_USED){ if ($this->requestUrl == '/'){ $this->site = $this->domain['site']; } else { $this->siteUrl = str_replace('\\','/',dirname($_SERVER['SCRIPT_NAME'])); if (strlen($this->siteUrl) > 1){ $this->requestUrl = $request_rel = preg_replace("#^{$this->siteUrl}#",'',$this->requestUrl); } else { $this->siteUrl = false; } # Figure out website folder and remove it from $this->requestUrl $this->siteFolder = current(explode('/',substr($this->requestUrl,1))); $this->requestUrl = preg_replace("#^\/{$this->siteFolder}#",'',$this->requestUrl); # Find site with website folder foreach ($this->sites as $sid => $aSite){ if ($aSite['sitename'] == $this->siteFolder){ $this->site = $sid; break; } } # Search historical website folder names if (!$this->site){ foreach($this->sites as $sid => $aSite){ if (in_array($this->siteFolder,$aSite['historical'])){ $this->redirect($this->siteUrl.'/'.$this->sites[$sid]['sitename'].$this->requestUrl,HTTP_STATUS_301, "Historical site folder hit"); } } } # Site folder corresponds to an existing site id. Use it. if (!$this->site && is_numeric($this->siteFolder) && $this->sites[$this->siteFolder]){ $this->site = $this->siteFolder; } # Domain standard site if (!$this->site && $this->domain['site']){ $this->site = $this->domain['site']; } # Super duper fallback if (!$this->site){ $this->site = 1; } if ((!isset($aSite['historical']) || !in_array($this->siteFolder,$aSite['historical'])) && $this->siteFolder != $this->sites[$this->site]['sitename']){ $this->unknownSiteFolder = true; } $this->siteFolder = "/".$this->sites[$this->site]['sitename']; } } else { #$this->site = $this->domain["site"]; # Do we _really_ need this one? Cant we get all the info we need from domain.php + current domain? $this->site = URI_HANDLER_DEFAULT_SITE; } } /** * Generic method for setting a header. * @param string $header */ public function setHeader($header, $code=false) { if ($code) { header($header, true, $code); } else { header($header); } } /** * Initializes timestamp for debug session */ private function setDebugTimeStamp() { if ($this->debug) { $this->debugTimestamp = $_GET['_seo_time'] ? (int) $_GET['_seo_time'] : microtime(1); } } /** * Magic get method. * @param string $name * @return mixed */ function __get($name) { return $this->$name; } /** * Redirects the visitor to the mobile web site */ private function mobileRedirect() { $redirect_url_mobile = false; if ($this->redirectToMobileDomain) { $redirect_url_domain = ""; foreach ($this->domains as $mobileDomain) { if ($mobileDomain["mobile_domain"] === true && $mobileDomain["region"] == $this->domain["region"]) { $redirect_url_domain = ($_SERVER["HTTPS"]?"https":"http")."://".$mobileDomain["url"]; $redirect_url_mobile = $redirect_url_domain.$this->requestUrl; break; } } if ($redirect_url_mobile) { // Look for mobile page equivalent and load it's rewrite. $rewriteRow = $this->getRewriteRow($this->site, $this->domain["region"], "web_page-s".$this->site, $this->requestUrl); // Only look if we have found a rewrite if ($redirect_url_domain && !empty($rewriteRow["item_table"]) && !empty($rewriteRow["item_id"])){ $rel = $this->getRelation($rewriteRow["item_table"], $rewriteRow["item_id"], "mobile"); if (!empty($rel["sys_rid"]) && !empty($rel["sys_rtable"])) { $rewrite = array( "item_table" => $rel["sys_rtable"], "item_id" => $rel["sys_rid"], "region" => $this->domain['region'], ); $redirect = $this->getRedirect($this->site, $rewrite, 0); if (!empty($redirect)) { $redirect_url_mobile = $redirect_url_domain.$redirect; } } } $this->redirect($redirect_url_mobile, 301); } } return false; } /** * Sets start page variables */ private function setStartPageInfo() { # Figure out correct start page for current site and domain if (SITE_FOLDERS_USED && $this->domain['url'] == '*' && $this->sites[$this->site]['primary_startpage']){ $startPage = $this->sites[$this->site]['primary_startpage']; } else { $startPage = $this->domain['startpage']; } if ($startPage) { $aStartPage = explode('/',$startPage); $this->startPage = $aStartPage[0].'/'.$aStartPage[1]; #@todo Why do we have this? Should not the other site variables be enough? $this->startPageSite = substr($aStartPage[0],10); #@todo Why do we have this? Should not the other region variables be enough? $this->startPageRegion = $aStartPage[2] ? $aStartPage[2] : ($this->domain['region']?$this->domain['region']:1); $this->aStartPage = $aStartPage; } else { $this->startPage = false; } if ($this->debug) { $this->debugStack['site'] = $this->site; $this->debugStack['document_root'] = $this->documentRoot; $this->debugStack['site_url'] = $this->siteUrl; $this->debugStack['request_path'] = $this->requestPath; $this->debugStack['request_url'] = $this->requestUrl; $this->debugStack['checkpoint_'.__LINE__] = microtime(1)-$this->debugTimestamp; } } private function isRewriteItem($rewrite) { if (is_array($rewrite) && !empty($rewrite) && isset($rewrite['item_id']) && isset($rewrite['item_table'])) { return true; } return false; } private function isRewritePath($rewrite) { if (is_string($rewrite)) { return true; } return false; } /** * @todo Re-write this method so it only does one thing. * * Crude method that does one of the following: * - Returns the current rewrite * - Redirects the visitor to another URL/domain * @return array|bool|null|string */ public function getIncludeFileOrRedirect() { if (SITE_FOLDERS_USED && $this->sites[$this->site]['website_live']){ return 'index.php'; } $this->requestRel = $this->requestUrl; $this->setStartPageInfo(); $this->requestUrl = DB::escape($this->requestUrl); $rewrite = $this->getRewrite($this->requestUrl); # Rewrite or redirect if ($this->isRewritePath($rewrite)) { return $rewrite; } elseif ($this->isRewriteItem($rewrite)) { $item = "{$rewrite['item_table']}/{$rewrite['item_id']}"; if ($this->startPage == $item && $this->requestUrl != '/' && $rewrite['region'] == $this->domain['region']){ $this->redirect("{$this->siteUrl}{$this->siteFolder}/",HTTP_STATUS_301); } switch ($rewrite['status']){ # Permanently moved. Redirect case 301: $this->redirect($this->siteUrl.$this->siteFolder.$rewrite['target'],HTTP_STATUS_301); break; # Error rewrite case 404: $target = $this->documentRoot.$this->siteUrl.$this->siteFolder.$rewrite['target']; if (file_exists($target)){ header(HTTP_STATUS_404); header("Status: 404 Not Found"); chdir(dirname($target)); $GLOBALS["basehref"] = ($_SERVER["HTTPS"]?"https":"http")."://".$_SERVER["HTTP_HOST"].dirname($this->siteUrl.$this->siteFolder.$rewrite['target']).'/'; $_SERVER["SCRIPT_NAME"] = $_SERVER["PHP_SELF"] = $this->siteUrl.$this->siteFolder.$rewrite['target']; $GLOBALS["CURRENT_URL"] = $this->siteUrl.$this->siteFolder.'/'.$rewrite['url']; $GLOBALS["ITEM_URL"] = $rewrite['url']; // Set site url to generate absolute links define("SD_SITE_URL",$this->siteUrl.$this->siteFolder.'/'); if ($this->debug) { $this->debugStack['checkpoint_'.__LINE__] = microtime(1)-$this->debugTimestamp; } return $target; } break; # Normal rewrite default: $target = $this->documentRoot.$this->siteUrl.$this->siteFolder.$rewrite['target']; if (file_exists($target)){ if ($item && substr($item,0,8) != 'web_page'){ if(stripos($item,'_grp')){ $GLOBALS["webpublish_load_group"] = $item; } else { $GLOBALS["webpublish_load_item"] = $item; } if ($this->debug) { $this->debugStack["webpublish_load_group"] = $GLOBALS["webpublish_load_group"]; } if ($this->debug) { $this->debugStack["webpublish_load_item"] = $GLOBALS["webpublish_load_item"]; } } chdir(dirname($target)); $GLOBALS["basehref"] = ($_SERVER["HTTPS"]?"https":"http")."://".$_SERVER["HTTP_HOST"].dirname($this->siteUrl.$this->siteFolder.$rewrite['target']).'/'; $_SERVER["SCRIPT_NAME"] = $_SERVER["PHP_SELF"] = $this->siteUrl.$this->siteFolder.$rewrite['target']; $GLOBALS["CURRENT_URL"] = $this->siteUrl.$this->siteFolder.'/'.$rewrite['url']; $GLOBALS["ITEM_URL"] = $rewrite['url']; // Set site url to generate absolute links define("SD_SITE_URL",$this->siteUrl.$this->siteFolder.'/'); if ($this->debug) { $this->debugStack['checkpoint_'.__LINE__] = microtime(1)-$this->debugTimestamp; } return $target; } break; } } return false; } /** * Redirects the visitor to another URL * @param string $url URL to redirect to. * @param int $status HTTP status (301, 404 and so on) for the given redirect. * @param string $msg Debug message */ public function redirect($url,$status = 0,$msg = ''){ // The 307 status is set to keep the POST in the rare case of posting to a url that gets redirected. // This will cause a client side popup warning at least in Firefox. if ($status == HTTP_STATUS_301 && $_SERVER['REQUEST_METHOD'] == 'POST' && $url != '/'){ $status = HTTP_STATUS_307; } // Add GET query string parse_str($_SERVER["QUERY_STRING"], $queryString); ksort($queryString); $url .= $_GET ? '?'.http_build_query($queryString) : false; if ($status){ $this->setHeader($status); } if ($this->debug){ if ($msg) { $this->debugStack["action_message"] = $msg; } $this->debugStack["checkpoint_redirect"] = microtime(1)-$this->debugTimestamp; $this->debugStack["action"] = "redirect to $url"; $debugQuery = http_build_query(array('_seo'=>$this->debugStack,'_seo_time'=>$this->debugStack)); $url .= (strpos($url,'?')?'&':'?').$debugQuery; } $this->setHeader("Location: $url"); $this->stopUriHandler(); } /** * Outputs debug text and kills the script. * @param string $txt Debug message */ public function stopUriHandler($txt = ''){ if ($this->debug){ $this->debugStack[] = array($_GET,$_POST,$_SERVER); if ($txt) { $this->debugStack['exit'] = $txt; } $this->debugStack['time'] = microtime(1)-$this->debugTimestamp; if ($_GET['_seo']){ $this->debugStack['_seo'] = $_GET['_seo']; } unset($_GET['_seo'],$_GET['_seo_debug'],$_GET['_seo_time']); $this->debugStack['_GET'] = $_GET; if (function_exists('xdebug_is_enabled')){ var_dump($this->debugStack); } else { echo ""; var_dump($this->debugStack); echo ""; } } die($txt); } /** * Fetches URL to redirect visitor to. * * @param int $site Site ID (1-inf) * @param array $rewrite Rewrite data * @param int $query_domain 0 for regular URLS, -1 for mobile ones. * @return bool|string Returns string URL or false. */ public function getRedirect($site,$rewrite,$query_domain){ $query = "SELECT url FROM `seo_rewrites-s{$site}` WHERE item_table = '{$rewrite['item_table']}' AND item_id = '{$rewrite['item_id']}' AND region = '{$rewrite['region']}' AND domain=$query_domain"; $rs = DB::query($query); $aRewrite = DB::fetchOne($rs); if ($aRewrite['url']){ return "/{$aRewrite['url']}"; } else { return false; } } /** * Fetches URL rewrite * @param int $site Site ID (1-inf) * @param int $region Region ID (1-inf) * @param string $item_type SiteDirect item table (web_page-sn( * @param string $url * @param int $query_domain * @return array|bool|null */ public function getRewriteRow($site, $region, $item_type, $url, $query_domain=0) { $url = DB::escape($url); $url = substr($url, 1); // Removed first slash $query = "SELECT * FROM `seo_rewrites-s{$site}` WHERE url='{$url}' AND item_table='{$item_type}' AND region={$region} AND domain=$query_domain"; $rs = DB::query($query); $aRewrite = DB::fetchOne($rs); if ($aRewrite['url']){ return $aRewrite; } else { return false; } } /** * Fetches item relation * @param string $table Item table (web_page-sn and similar) * @param int $id Item ID (1-inf) * @param string $subtype Item subtype * @return array|bool|null */ public function getRelation($table, $id, $subtype) { $query = "SELECT * FROM `{$table}_pub_rel` WHERE sys_rtable='{$table}' AND sys_id=$id AND sys_subtype='$subtype' LIMIT 1"; $rs = DB::query($query); $aRel = DB::fetchOne($rs); if ($aRel['sys_rid']){ return $aRel; } else { return false; } } /** * @param $settingRedirectMode */ public function setMobileRedirect($settingRedirectMode) { @session_start(); if ($_REQUEST["viewmode"]) { if ($_REQUEST["viewmode"] == "web") { $_SESSION["webpublish"]["viewmode"] = "web"; } elseif ($_REQUEST["viewmode"] == "mobile") { $_SESSION["webpublish"]["viewmode"] = "mobile"; } else { unset($_SESSION["webpublish"]["viewmode"]); } } /* This is for testing purposes. When this is set, the detect check is made on every page load instead of being cached. Normally a user do not switch user agents and no caching problem occurs */ if ($_REQUEST["overrideviewmode"]) { if ($_REQUEST["overrideviewmode"] == "true") { $_SESSION["overrideviewmode"] = true; } else { unset($_SESSION["overrideviewmode"]); } } // Only redirect in the uri_handler that exists in the site folder if (SITE_FOLDERS_USED === 0) { // Remove true after "live" to improve performance if ($_SESSION["overrideviewmode"] || empty($_SESSION["webpublish"]["viewmode"])) { $mobile_detect = new Mobile_Detect(); if ($mobile_detect->isTablet()) { $_SESSION["webpublish"]["viewmode"] = $settingRedirectMode; } elseif ($mobile_detect->isMobile()) { $_SESSION["webpublish"]["viewmode"] = "mobile"; } else { $_SESSION["webpublish"]["viewmode"] = "web"; } } // User has moved to the web mode using a viewmode link so we disable the redirect if (!$this->mobileDomain && $_SESSION["webpublish"]["viewmode"] != "web") { if ($this->debug) { $this->debugStack['checkpoint_'.__LINE__] = microtime(1)-$this->debugTimestamp; } $this->redirectToMobileDomain = true; } } } /** * * Locates redirects * IMPORTANT: Call to this method is generated from function_seo.php. IDE warnings about this method not being used should be ignored. * @param array|bool $rewrite Existing rewrite * @param string $request_url * @param int $site * @param int $query_domain * @param string $site_folder */ private function getRootQueryRedirects(&$rewrite, $request_url, $query_domain, &$site_folder) { ################################################################################################### # Try to get rewrite with query(primarily for "old URLs") if (!$rewrite && !empty($_GET)){ $old_url = substr($request_url,1); $__get = $_GET; ksort($__get); $old_url = DB::escape($old_url."?".http_build_query($__get)); $queryRedirect = "SELECT * FROM `seo_redirects-s{$this->site}` WHERE url = '{$old_url}' AND type = 1 AND domain={$query_domain}"; $rRewrite = DB::query($queryRedirect); $rewrite = DB::fetchAssoc($rRewrite); if ($rewrite){ $_GET = array(); if (SITE_FOLDERS_USED && !$site_folder) { $site_folder = '/'.$this->sites[$this->site]['sitename']; } } $this->debugStack['old_redirect_query'] = $rewrite; } ################################################################################################### # Someone is navigating to the template page with a GET item ID. Redirect them to the correct URL. if ($rewrite && isset($_GET["item"]) && !empty($_GET["item"]) && $rewrite["item_table"] == "web_page-s{$this->site}") { $itemId = DB::escape($_GET["item"]); $aItem = explode('/',$itemId); // How do we find out that a page is a template page? $pageIsItemTypeTemplatePage = false; $query = "SELECT setting FROM `web_page-s{$this->site}_pub_r{$this->region}` WHERE sys_id={$rewrite["item_id"]}"; // Load the current page. We have to check if it is a template web page. $pRes = DB::query($query); $tplPage = DB::fetchAssoc($pRes); if (!empty($tplPage['setting'])) { $settings = unserialize($tplPage['setting']); if (is_array($settings) && isset($settings['template_page']["itemtype"]) && !empty($settings['template_page']["itemtype"])) { if (substr($aItem[0], 0, strlen($settings['template_page']["itemtype"])) == $settings['template_page']["itemtype"]) { // Only perform the redirect if it is the template page for the product aswell, so we dont get lots of strange redirects $query = "SELECT target FROM `seo_rewrites-s{$this->site}` WHERE item_table='{$aItem[0]}' AND item_id={$aItem[1]} AND region={$this->region} AND domain={$query_domain}"; $pRes = DB::query($query); $aRewrite = DB::fetchAssoc($pRes); if (!empty($aRewrite['target'])) { $aTarget = explode('/', $aRewrite['target']); // Target = /1.0.1.0/8/1/index.php, we want "8" which is the page sys_id if (isset($aTarget[2]) && !empty($aTarget[2]) && $aTarget[2] == $rewrite['item_id']) { // Only redirect if the products template page is the page we are on. If we redirect to another page we break functionality. $pageIsItemTypeTemplatePage = true; } } if ($this->debug) { $this->debugStack['checkpoint_'.__LINE__] = microtime(1)-$this->debugTimestamp; } } } } if ($pageIsItemTypeTemplatePage) { // Ok, now we need to redirect to the correct page. Reset the rewrite and prepare for redirection. $rewrite = array( "status" => 301, "item_table" => $aItem[0], "item_id" => $aItem[1], "region" => $this->region, "domain" => $query_domain, ); if ($this->debug) { $this->debugStack['checkpoint_'.__LINE__] = microtime(1)-$this->debugTimestamp; } } } } /** * Fetches the rewrite for a given URL * @todo Refactor this method so that we do not have a method with 300 lines of code + generated code. * * @param string $request_url * @return array|bool|null|string */ public function getRewrite($request_url){ $loadItem = false; // Generated below $aResult = array(); $rewrite = false; $redirect = false; // We set it here so we can get the mobile start page if needed. We set it again later when we know if we are looking at an item or not. if ($this->mobileDomain) { $query_domain = -1; } else { $query_domain = 0; } $GLOBALS["query_domain"] = $query_domain; // @todo move this to a setter method so we don't have to parse the class // Root query code goes below here if ($this->redirectType == 'root_query') { $this->getRootQueryRedirects($rewrite, $request_url, $query_domain, $site_folder); } // Root query code goes above here if (!$rewrite && !$this->unknownSiteFolder){ ################################################################################################### # Get rewrite for root url (or mobile root url) if (in_array($request_url,array('/',$this->siteFolder, $this->siteFolder.'/')) && $this->startPage){ // Since start page always is a web page, domain should be zero (web pages share rewrites with mobile pages) $query = "SELECT * FROM `seo_rewrites-s{$this->startPageSite}` WHERE item_table = '{$this->aStartPage[0]}' AND item_id = '{$this->aStartPage[1]}' AND region = {$this->startPageRegion} AND domain=0"; $rRewrite = DB::query($query); $numResults = DB::getNumRows($rRewrite); if ($this->debug && ($numResults > 1)) { $this->debugStack['ambiguous'] = $numResults; } $rewrite = DB::fetchAssoc($rRewrite); if ($rewrite){ $rewrite['url'] = ''; # Apply custom index code, which may or may not redirect itself # @todo The custom index file should run in its own namespace so that it cannot screw up things in here. if (file_exists('custom_index.php')){ $redirect = false; #$inner = !SITE_FOLDERS_USED; /** @noinspection PhpIncludeInspection */ include('custom_index.php'); } if ($redirect){ if(SITE_FOLDERS_USED && !preg_match("/^".$this->sites[$this->startPageSite]['sitename']."/", $redirect)){ $redirect = "{$this->sites[$this->startPageSite]['sitename']}/$redirect"; } $rewrite['target'] = "/$redirect"; $rewrite['status'] = 301; $this->siteFolder = false; } elseif(SITE_FOLDERS_USED){ if (!$this->siteFolder || $this->site != $this->startPageSite) { $this->siteFolder = '/'.$this->sites[$this->startPageSite]['sitename']; } } } if ($this->debug) { $this->debugStack['startpage_query'] = $rewrite; } ################################################################################################### # Get normal rewrite } else { $this_url = substr($request_url,1); # Generate url with alternative slash ending $altSlashEnd = substr($this_url,-1) == '/' ? substr($this_url,0,-1) : $this_url.'/'; if ($this->debug) { $this->debugStack['alt_slash_end'] = $altSlashEnd; } // "true" gets sought and replaced in SEO_GenerateRewriteFiles $combineRegionWithUrl = true; if ($combineRegionWithUrl) { $query = "SELECT * FROM `seo_rewrites-s{$this->site}` WHERE region = ".$this->domain['region']." AND (url = '{$this_url}' OR url = '{$altSlashEnd}') AND (item_table='web_page-s{$this->site}' OR (item_table !='web_page-s{$this->site}' AND domain={$query_domain})) ORDER BY region"; } else { $query = "SELECT * FROM `seo_rewrites-s{$this->site}` WHERE (url = '{$this_url}' OR url = '{$altSlashEnd}') AND (item_table='web_page-s{$this->site}' OR (item_table !='web_page-s{$this->site}' AND domain={$query_domain})) ORDER BY region"; } $rRewrite = DB::query($query); $numResults = DB::getNumRows($rRewrite); if (!$numResults) { if ($combineRegionWithUrl) { $resultQuery = "SELECT * FROM `seo_redirects-s{$this->site}` WHERE region = ".$this->domain['region']." AND (url = '{$this_url}' OR url = '{$altSlashEnd}') AND (item_table='web_page-s{$this->site}' OR (item_table !='web_page-s{$this->site}' AND domain={$query_domain})) ORDER BY type DESC, created DESC"; } else { $resultQuery = "SELECT * FROM `seo_redirects-s{$this->site}` WHERE (url = '{$this_url}' OR url = '{$altSlashEnd}') AND (item_table='web_page-s{$this->site}' OR (item_table !='web_page-s{$this->site}' AND domain={$query_domain})) ORDER BY type DESC, created DESC"; } $rRewrite = DB::query($resultQuery); $numResults = DB::getNumRows($rRewrite); } if ($this->debug && ($numResults > 1)) { $this->debugStack['ambiguous'] = $numResults; } $rewrite = DB::fetchAssoc($rRewrite); # Check if url with alternative slash ending is the one we got if ($rewrite && $rewrite['url'] == $altSlashEnd && !$rewrite['status']){ $rewrite['status'] = 301; $rewrite['target'] = '/'.$altSlashEnd; if ($this->debug) { $this->debugStack['alt_slash_hit'] = "yes"; } } if ($this->debug) { $this->debugStack['normal_query'] = $rewrite; } } } if ($this->debug) { $this->debugStack['checkpoint_'.__LINE__] = microtime(1)-$this->debugTimestamp; } ################################################################################################### # Check if a uri with site folder has been requested and site folders are not used. i.e the domain is pointed to the site folder. if (!$rewrite && !SITE_FOLDERS_USED){ $this_url = substr($request_url,1); $aRequest = explode('/',$this_url); if ($aRequest[0] == $this->sites[$this->site]['sitename'] || in_array($aRequest[0],$this->sites[$this->site]['historical'])){ array_shift($aRequest); $this_url = implode('/',$aRequest); $aResult = $this->getRewrite("/$this_url"); if($aResult["status"] == "301"){ return $aResult; } else { $this->redirect("/$this_url",HTTP_STATUS_301,"Redirecting from 'site folder url'"); } } } if ($this->debug) { $this->debugStack['checkpoint_'.__LINE__] = microtime(1)-$this->debugTimestamp; } // @todo move this to a setter method so we don't have to parse the class if ($this->redirectType == 'query') { $this->getRootQueryRedirects($rewrite, $request_url, $query_domain, $site_folder); } ################################################################################################### # Try to find physical file if ((!$rewrite || $rewrite['status'] == 404) && file_exists($this->requestPath) && $this->requestRel != '/' && $this->requestRel != $this->siteFolder.'/'){ if ($this->debug) { $this->debugStack[] = "File Exists"; } $this_url = $request_url; # Request is a directory. Try to find an index file if (is_dir($this->requestPath)){ if ($this->debug) { $this->debugStack[] = "File Is Dir"; } $allowed_indices = array('index.php','index.html','index.htm'); $file_found = false; foreach ($allowed_indices as $index){ if (file_exists($this->requestPath.$index)){ $file_found = true; $this_url .= $index; $this->requestRel .= $index; $this->requestPath .= $index; break; } } } else { $file_found = true; } if ($this->debug) { $this->debugStack['checkpoint_'.__LINE__] = microtime(1)-$this->debugTimestamp; } if ($file_found) { # Check if file is located in a SiteDirect system file directory or the request is POST if (strpos($this->requestRel,'/sd_') === 0 || $_SERVER['REQUEST_METHOD'] == 'POST'){ if($this->debug) { $this->debugStack[] = "Sys File or Post: Use physical file"; } chdir(dirname($this->requestPath)); $_SERVER["SCRIPT_NAME"] = $_SERVER["PHP_SELF"] = $this->siteUrl.$this->siteFolder.$this->requestRel; return $this->requestPath; } # Check if there is a fancier url for the requested page $fancyUrlQuery = "SELECT url,item_id,item_table FROM `seo_rewrites-s{$this->site}` WHERE target = '{$this_url}' AND domain=0"; $rResult = DB::query($fancyUrlQuery); $numResults = DB::getNumRows($rResult); if ($this->debug && ($numResults > 1)) { $this->debugStack['ambiguous'] = $numResults; } if ($numResults > 1){ while ($row = DB::fetchAssoc($rResult)) { if ($row['item_table'] == 'web_page-s'.$this->site) { @session_start(); $itemType = $_SESSION["webpublish"][$row['item_id']]["itemtype"]; $groupType = $_SESSION["webpublish"][$row['item_id']]["grouptype"]; $lastLoadedItem = $_SESSION["webpublish"][$row['item_id']][$itemType]["itemid"]; $lastLoadedGroup = $_SESSION["webpublish"][$row['item_id']][$groupType]["groupid"]; if ($itemType && $lastLoadedItem){ $loadItem = $lastLoadedItem; } elseif ($groupType && $lastLoadedGroup) { $loadItem = $lastLoadedGroup; } break; } } if ($loadItem){ list ($item_table,$item_id) = explode('/',$loadItem); while ($row = DB::fetchAssoc($rResult)){ if ($row['item_table'] == $item_table && $row['item_id'] == $item_id){ $aResult = $row; } } } } else { $aResult = DB::fetchAssoc($rResult); } # Fancy URL found if ($aResult){ $this->redirect( $this->siteUrl.$this->siteFolder.'/'.$aResult['url'], HTTP_STATUS_301, "Fancy URI found" ); # Use physical file } else { chdir(dirname($this->requestPath)); $_SERVER["SCRIPT_NAME"] = $_SERVER["PHP_SELF"] = $this->siteUrl.$this->siteFolder.$this->requestRel; return $this->requestPath; } } } if ($this->debug) { $this->debugStack['checkpoint_'.__LINE__] = microtime(1)-$this->debugTimestamp; } ################################################################################################### # Get target for redirects if ($rewrite['status'] == 301 && !$rewrite['target']){ $rewrite['target'] = $this->getRedirect($this->site,$rewrite, $query_domain); if ($this->debug) { $this->debugStack['get_target'] = $rewrite['target']; } if (!$rewrite['target']){ $rewrite['status'] = 404; } } if ($this->debug) { $this->debugStack['checkpoint_'.__LINE__] = microtime(1)-$this->debugTimestamp; } ################################################################################################### # Get 404 page if ($this->mobileDomain) { $page_404 = $this->sites[$this->site]['error_page_mobile_404']; } else { $page_404 = $this->sites[$this->site]['error_page_404']; } if ((!$rewrite || $rewrite['status'] == 404 || empty($rewrite['target'])) && $page_404){ if ($this->debug) { if (isset($rewrite['target']) && empty($rewrite['target'])) { $this->debugStack['checkpoint_'.__LINE__] = microtime(1)-$this->debugTimestamp; } } $aItem = explode('/',$page_404); $region = $aItem[2] ? $aItem[2] : $this->region; $query = "SELECT * FROM `seo_rewrites-s{$this->site}` WHERE item_table = '{$aItem[0]}' AND item_id = '{$aItem[1]}' AND region = '{$region}' AND domain=0"; // Always a web page. We cannot have a product as 404 can we? ;) $rRewrite = DB::query($query); $numResults = DB::getNumRows($rRewrite); if ($this->debug && ($numResults > 1)) { $this->debugStack['ambiguous'] = $numResults; } $rewrite = DB::fetchAssoc($rRewrite); $rewrite['status'] = 404; } elseif ($rewrite['status'] == 404){ $rewrite = false; } if ($this->debug) { $this->debugStack['checkpoint_'.__LINE__] = microtime(1)-$this->debugTimestamp; } ################################################################################################### $GLOBALS["current_rewrite"] = $rewrite; return $rewrite; } /** * Initialization method. * @return array|bool|null|string */ public function execute() { # Redirect to mobile site if necessary $this->mobileRedirect(); $include = $this->getIncludeFileOrRedirect(); $this->debugStack["include"] = $include; return $include; } } /** * * * * * * * NEVER NEVER EVER REMOVE THE 'comments' BELOW. This is parsed before this file is published to the web site. Removing them WILL cause this file to stop functioning as intended. * The "macros" below are generated into this file during the publish phase of a web page. * * * * * */ // @This should actually be moved into the class, but I rather not generate code into the class itself. Perhaps a solution is to use a setter here and place the real logic in the. // Default setting, no vary header // Should we redirect to another domain due to being a mobile visitor? # Generates \$uri->setMobileRedirect('$mode'); or empty string. ################################################################################################### $uri->redirectType = 'query'; ################################################################################################### /** * * * * * * * NEVER NEVER EVER REMOVE THE 'comments' ABOVE. This is parsed before this file is published to the web site. Removing them WILL cause this file to stop functioning as intended. * The "macros" below are generated into this file during the publish phase of a web page. * * * * * */ $includePath = $uri->execute(); if ($includePath){ include($includePath); $uri->stopUriHandler(); } # If we fail to find a rewrite, send a 404 and terminate script. $uri->setHeader(HTTP_STATUS_404); $uri->setHeader("Status: 404 Not Found"); $output = << Not found

Not found

The page cannot be found. In addition, no 404 page is configured for this web site.

CODE; $uri->stopUriHandler($output);