Index: admin_templates/site_domains/site_domain_edit.tpl =================================================================== --- admin_templates/site_domains/site_domain_edit.tpl (revision 0) +++ admin_templates/site_domains/site_domain_edit.tpl (revision 0) @@ -0,0 +1,111 @@ + + + + + + + + + + + + +
+ +
+ + + + + + + + + + + onchange="update_checkbox(this, document.getElementById(''));"/> + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + \ No newline at end of file Index: admin_templates/site_domains/site_domain_list.tpl =================================================================== --- admin_templates/site_domains/site_domain_list.tpl (revision 0) +++ admin_templates/site_domains/site_domain_list.tpl (revision 0) @@ -0,0 +1,48 @@ + + + + + + + + + + + +
+ +
+ + + + \ No newline at end of file Index: install/english.lang =================================================================== --- install/english.lang (revision 13140) +++ install/english.lang (working copy) @@ -13,6 +13,7 @@ QXV0bw== QXV0b21hdGlj QXZhaWxhYmxlIENvbHVtbnM= + QXZhaWxhYmxlIEl0ZW1z QmFja2dyb3VuZA== Qm9yZGVycw== QnJvd3NlIE1vZGU= @@ -56,8 +57,10 @@ U2VjdGlvbiBOYW1l Q2hhbmdlcw== Q2hhcnNldA== + Q291bnRyeQ== Q3JlYXRlZCBPbg== RGVzY3JpcHRpb24= + RG9tYWluIE5hbWU= RHVyYXRpb24= RWZmZWN0aXZl RW1haWw= @@ -161,6 +164,7 @@ U2Vzc2lvbiBTdGFydA== TmFtZQ== U29ydCBieQ== + U1NMIFVybA== U3RhdHVz U3RvcCBXb3Jk U3ViamVjdA== @@ -170,6 +174,7 @@ SXRlbQ== SXRlbSBUeXBl VGVtcGxhdGU= + VGhlbWU= VGhlc2F1cnVzIFRlcm0= VGhlc2F1cnVzIFR5cGU= VGl0bGU= @@ -556,6 +561,7 @@ QWN0aW9u QWRkcmVzcyBMaW5lIDE= QWRkcmVzcyBMaW5lIDI= + TWVzc2FnZXMgZnJvbSBTaXRlIEFkbWluIGFyZSBmcm9t QWRtaW4gUHJpbWFyeQ== QWR2YW5jZWQgQ1NT QWR2YW5jZWQgU2VhcmNo @@ -602,6 +608,8 @@ RGlzcGxheQ== RGlzcGxheSBpbiBHcmlk RmllbGQgTGFiZWw= + UmFuZ2Ugb2YgSVBz + RG9tYWluIE5hbWU= QXMgUGxhaW4gVGV4dA== RHVyYXRpb24= RWRpdG9ycyBQaWNr @@ -679,6 +687,7 @@ TGFuZ3VhZ2U= TGFuZ3VhZ2UgRmlsZQ== TGFuZ3VhZ2UgSUQ= + TGFuZ3VhZ2Vz TGFzdCBOYW1l TGFzdCBSdW4gT24= TGFzdCBSdW4gU3RhdHVz @@ -743,6 +752,7 @@ UHJpbWFyeSBMYW5ndWFnZSBQaHJhc2U= T3JkZXI= UmF0aW5n + Rm9yY2UgUmVkaXJlY3QgKHdoZW4gdXNlcidzIElQIG1hdGNoZXMp S2V5d29yZA== VHlwZQ== UmVtb3RlIFVSTA== @@ -765,6 +775,7 @@ TmFtZQ== U2tpcCBGaXJzdCBSb3c= U29ydCBWYWx1ZXM= + U1NMIEZ1bGwgVVJM U3RhdGU= U3RhdHVz U3RvcCBXb3Jk @@ -780,6 +791,8 @@ VGV4dCBBbGlnbg== VGV4dCBEZWNvcmF0aW9u VGV4dCBWZXJzaW9u + VGhlbWU= + VGhlbWVz VGhlc2F1cnVzIFRlcm0= VGhlc2F1cnVzIFR5cGU= VGhvdXNhbmRzIFNlcGFyYXRvcg== @@ -814,7 +827,9 @@ SGlkZQ== QWxsIEZpbGVz Q1NWIEZpbGVz + U2luZ2xlIElQIG9yIHJhbmdlIHJlY29yZCBwZXIgbGluZSAoZm9ybWF0czogMS4yLjMuNCBvciAxLjIuMyBvciAxLjIuMy4zMi0xLjIuMy41NCBvciAxLjIuMy4zMi8yNyBvciAxLjIuMy4zMi8yNTUuMjU1LjI1NS4yMjQp SW1hZ2UgRmlsZXM= + aHR0cHM6Ly93d3cuZG9tYWluLmNvbS9wYXRo SG90 SFRNTA== SUQgRmllbGQ= @@ -1120,6 +1135,7 @@ U2VhcmNoIFVzZXJz VmFsdWVz U2VsZWN0IENvbHVtbnM= + U2VsZWN0ZWQgSXRlbXM= U2VsZWN0aW5nIFNlY3Rpb25z T25lIGZpZWxkIGZvciBlYWNoIHNlY3Rpb24gbGV2ZWw= Q2xvbmU= @@ -1344,6 +1360,7 @@ QWRkaW5nIEN1c3RvbSBGaWVsZA== QWRkaW5nIEZpbGU= QWRkaW5nIE1haWxpbmcgTGlzdA== + QWRkaW5nIFNpdGUgRG9tYWlu QWRkaW5nIFNraW4= QWRkaW5nIFNwZWxsaW5nIERpY3Rpb25hcnk= QWRkaW5nIFN0b3AgV29yZA== @@ -1388,6 +1405,7 @@ RWRpdGluZyBFbWFpbCBFdmVudA== RWRpdGluZyBGaWxl RWRpdGluZyBNZW1iZXJzaGlw + RWRpdGluZyBTaXRlIERvbWFpbg== RWRpdGluZyBTa2lu RWRpdGluZyBTcGVsbGluZyBEaWN0aW9uYXJ5 RWRpdGluZyBTdG9wIFdvcmQ= @@ -1460,6 +1478,7 @@ U2VuZCBFLW1haWw= U2VuZGluZyBQcmVwYXJlZCBFLW1haWxz TWFpbCBoYXMgYmVlbiBzZW50IFN1Y2Nlc3NmdWxseQ== + U2l0ZSBEb21haW5z U3BlbGxpbmcgRGljdGlvbmFyeQ== U3RvcCBXb3Jkcw== U3RydWN0dXJlICYgRGF0YQ== @@ -1515,6 +1534,7 @@ TmV3IFBocmFzZQ== TmV3IENvbW1lbnQ= TmV3IFNlYXJjaCBGaWVsZA== + TmV3IFNpdGUgRG9tYWlu TmV3IFN0b3AgV29yZA== TmV3IFN0eWxlc2hlZXQ= TmV3IFRlcm0= Index: install/install_schema.sql =================================================================== --- install/install_schema.sql (revision 13151) +++ install/install_schema.sql (working copy) @@ -1095,4 +1095,46 @@ KEY SessionKey (SessionKey), KEY `Timestamp` (`Timestamp`), KEY MainPrefix (MainPrefix) -); \ No newline at end of file +); + +CREATE TABLE SiteDomains ( + DomainId int(11) NOT NULL AUTO_INCREMENT, + DomainName varchar(255) NOT NULL DEFAULT '', + DomainNameUsesRegExp tinyint(4) NOT NULL DEFAULT '0', + SSLUrl varchar(255) NOT NULL DEFAULT '', + SSLUrlUsesRegExp tinyint(4) NOT NULL DEFAULT '0', + AdminEmail varchar(255) NOT NULL DEFAULT '', + Country varchar(3) NOT NULL DEFAULT '', + BillingCountry varchar(3) NOT NULL DEFAULT '', + ShippingCountry varchar(3) NOT NULL DEFAULT '', + PrimaryLanguageId int(11) NOT NULL DEFAULT '0', + Languages varchar(255) NOT NULL DEFAULT '', + PrimaryThemeId int(11) NOT NULL DEFAULT '0', + Themes varchar(255) NOT NULL DEFAULT '', + PrimaryCurrencyId int(11) NOT NULL DEFAULT '0', + Currencies varchar(255) NOT NULL DEFAULT '', + PrimaryPaymentTypeId int(11) NOT NULL DEFAULT '0', + PaymentTypes varchar(255) NOT NULL DEFAULT '', + DomainIPRange text NOT NULL, + RedirectOnIPMatch tinyint(4) NOT NULL DEFAULT '0', + Priority int(11) NOT NULL DEFAULT '0', + PRIMARY KEY (DomainId), + KEY DomainName (DomainName), + KEY DomainNameUsesRegExp (DomainNameUsesRegExp), + KEY SSLUrl (SSLUrl), + KEY SSLUrlUsesRegExp (SSLUrlUsesRegExp), + KEY AdminEmail (AdminEmail), + KEY Country (Country), + KEY BillingCountry (BillingCountry), + KEY ShippingCountry (ShippingCountry), + KEY PrimaryLanguageId (PrimaryLanguageId), + KEY Languages (Languages), + KEY PrimaryThemeId (PrimaryThemeId), + KEY Themes (Themes), + KEY PrimaryCurrencyId (PrimaryCurrencyId), + KEY Currencies (Currencies), + KEY PrimaryPaymentTypeId (PrimaryPaymentTypeId), + KEY PaymentTypes (PaymentTypes), + KEY RedirectOnIPMatch (RedirectOnIPMatch), + KEY Priority (Priority) +); Index: install/remove_schema.sql =================================================================== --- install/remove_schema.sql (revision 13140) +++ install/remove_schema.sql (working copy) @@ -68,3 +68,4 @@ DROP TABLE FormSubmissions; DROP TABLE Forms; DROP TABLE Semaphores; +DROP TABLE SiteDomains; Index: install/upgrades.sql =================================================================== --- install/upgrades.sql (revision 13151) +++ install/upgrades.sql (working copy) @@ -1650,3 +1650,45 @@ DELETE FROM Phrase WHERE Phrase LIKE 'la_event_%'; DELETE FROM PersistantSessionData WHERE VariableName = 'phrases_columns_.'; + +CREATE TABLE SiteDomains ( + DomainId int(11) NOT NULL AUTO_INCREMENT, + DomainName varchar(255) NOT NULL DEFAULT '', + DomainNameUsesRegExp tinyint(4) NOT NULL DEFAULT '0', + SSLUrl varchar(255) NOT NULL DEFAULT '', + SSLUrlUsesRegExp tinyint(4) NOT NULL DEFAULT '0', + AdminEmail varchar(255) NOT NULL DEFAULT '', + Country varchar(3) NOT NULL DEFAULT '', + BillingCountry varchar(3) NOT NULL DEFAULT '', + ShippingCountry varchar(3) NOT NULL DEFAULT '', + PrimaryLanguageId int(11) NOT NULL DEFAULT '0', + Languages varchar(255) NOT NULL DEFAULT '', + PrimaryThemeId int(11) NOT NULL DEFAULT '0', + Themes varchar(255) NOT NULL DEFAULT '', + PrimaryCurrencyId int(11) NOT NULL DEFAULT '0', + Currencies varchar(255) NOT NULL DEFAULT '', + PrimaryPaymentTypeId int(11) NOT NULL DEFAULT '0', + PaymentTypes varchar(255) NOT NULL DEFAULT '', + DomainIPRange text NOT NULL, + RedirectOnIPMatch tinyint(4) NOT NULL DEFAULT '0', + Priority int(11) NOT NULL DEFAULT '0', + PRIMARY KEY (DomainId), + KEY DomainName (DomainName), + KEY DomainNameUsesRegExp (DomainNameUsesRegExp), + KEY SSLUrl (SSLUrl), + KEY SSLUrlUsesRegExp (SSLUrlUsesRegExp), + KEY AdminEmail (AdminEmail), + KEY Country (Country), + KEY BillingCountry (BillingCountry), + KEY ShippingCountry (ShippingCountry), + KEY PrimaryLanguageId (PrimaryLanguageId), + KEY Languages (Languages), + KEY PrimaryThemeId (PrimaryThemeId), + KEY Themes (Themes), + KEY PrimaryCurrencyId (PrimaryCurrencyId), + KEY Currencies (Currencies), + KEY PrimaryPaymentTypeId (PrimaryPaymentTypeId), + KEY PaymentTypes (PaymentTypes), + KEY RedirectOnIPMatch (RedirectOnIPMatch), + KEY Priority (Priority) +); Index: kernel/application.php =================================================================== --- kernel/application.php (revision 13128) +++ kernel/application.php (working copy) @@ -624,16 +624,56 @@ function GetPrimaryCurrency() { - if ($this->isModuleEnabled('In-Commerce')) { - $table = $this->getUnitOption('curr', 'TableName'); - return $this->Conn->GetOne('SELECT ISO FROM '.$table.' WHERE IsPrimary = 1'); + static $currency_iso = ''; + + if ($currency_iso) { + return $currency_iso; } + + if ($this->prefixRegistred('curr')) { + $currency_id = $this->siteDomainField('PrimaryCurrencyId'); + + $sql = 'SELECT ISO + FROM ' . $this->getUnitOption('curr', 'TableName') . ' + WHERE ' . ($currency_id > 0 ? 'CurrencyId = ' . $currency_id : 'IsPrimary = 1'); + $currency_iso = $this->Conn->GetOne($sql); + } else { - return 'USD'; + $currency_iso = 'USD'; } + + return $currency_iso; } /** + * Returns site domain field. When none of site domains are found false is returned. + * + * @param string $field + * @param bool $formatted + * @param string $format + */ + function siteDomainField($field, $formatted = false, $format = null) + { + static $site_domain = null; + + if ($this->isAdmin) { + // don't apply any filtering in administrative console + return false; + } + + if (!isset($site_domain)) { + $site_domain =& $this->recallObject('site-domain.current'); + /* @var $site_domain kDBItem */ + } + + if ($site_domain->isLoaded()) { + return $formatted ? $site_domain->GetField($field, $format) : $site_domain->GetDBField($field); + } + + return false; + } + + /** * Registers default classes such as ItemController, GridController and LoginController * * Called automatically while initializing Application @@ -1400,18 +1440,13 @@ $ssl = isset($params['__SSL__']) ? $params['__SSL__'] : null; if ($ssl !== null) { $session =& $this->recallObject('Session'); - $cookie_url = trim($session->CookieDomain.$session->CookiePath, '/.'); - if ($ssl) { - $target_url = defined('ADMIN') && ADMIN ? $this->ConfigValue('AdminSSL_URL') : false; - if (!$target_url) { - $target_url = $this->ConfigValue('SSL_URL'); - } - } - else { - $target_url = 'http://'.DOMAIN.$this->ConfigValue('Site_Path'); - } + /* @var $session Session */ - if (!preg_match('#'.preg_quote($cookie_url).'#', $target_url)) { + $target_url = rtrim($this->BaseURL('', $ssl, false), '/'); + $cookie_url = trim($session->CookieDomain . $session->CookiePath, '/.'); + + if (!preg_match('#' . preg_quote($cookie_url) . '#', $target_url)) { + // when SSL<->NON-SSL redirect to different domain pass SID in url $session->SetMode(smGET_ONLY); } } @@ -1895,24 +1930,33 @@ return $ret; } - function BaseURL($prefix='', $ssl=null) + function BaseURL($prefix = '', $ssl = null, $add_port = true) { if ($ssl === null) { - return PROTOCOL.SERVER_NAME.(defined('PORT')?':'.PORT : '').rtrim(BASE_PATH, '/').$prefix.'/'; + // stay on same encryption level + return PROTOCOL . SERVER_NAME . ($add_port && defined('PORT') ? ':' . PORT : '') . rtrim(BASE_PATH, '/') . $prefix . '/'; } - else { - if ($ssl) { - $base_url = defined('ADMIN') && ADMIN ? $this->ConfigValue('AdminSSL_URL') : false; - if (!$base_url) { - $base_url = $this->ConfigValue('SSL_URL'); - } - return rtrim($base_url, '/').$prefix.'/'; + if ($ssl) { + // going from http:// to https:// + $base_url = $this->isAdmin ? $this->ConfigValue('AdminSSL_URL') : false; + + if (!$base_url) { + $ssl_url = $this->siteDomainField('SSLUrl'); + $base_url = $ssl_url !== false ? $ssl_url : $this->ConfigValue('SSL_URL'); } - else { - return 'http://'.DOMAIN.(defined('PORT')?':'.PORT : '').rtrim( $this->ConfigValue('Site_Path'), '/').$prefix.'/'; - } + + return rtrim($base_url, '/') . $prefix . '/'; } + + // going from https:// to http:// + $domain = $this->siteDomainField('DomainName'); + + if ($domain === false) { + $domain = DOMAIN; + } + + return 'http://' . $domain . ($add_port && defined('PORT') ? ':' . PORT : '') . rtrim($this->ConfigValue('Site_Path'), '/') . $prefix . '/'; } function Redirect($t='', $params=null, $prefix='', $index_file=null) @@ -2129,6 +2173,14 @@ */ function ConfigValue($name) { + if ($name == 'Smtp_AdminMailFrom') { + $res = $this->siteDomainField('AdminEmail'); + + if ($res) { + return $res; + } + } + $res = array_key_exists($name, $this->ConfigHash) ? $this->ConfigHash[$name] : false; if ($res !== false) { return $res; Index: kernel/globals.php =================================================================== --- kernel/globals.php (revision 13128) +++ kernel/globals.php (working copy) @@ -560,17 +560,26 @@ return $ip_match; } - function netMatch($network, $ip) { + function netMatch($network, $ip) + { $network = trim($network); $ip = trim($ip); if ($network == $ip) { - // comparing 2 ip addresses directly + // comparing two ip addresses directly return true; } $d = strpos($network, '-'); - if ($d === false) { + if ($d !== false) { + // ip address range specified + $from = ip2long(trim(substr($network, 0, $d))); + $to = ip2long(trim(substr($network, $d + 1))); + + $ip = ip2long($ip); + return ($ip >= $from && $ip <= $to); + } + elseif (strpos($network, '/') !== false) { // sigle subnet specified $ip_arr = explode('/', $network); @@ -586,14 +595,8 @@ return ($ip_long & $mask) == ($network_long & $mask); } - else { - // ip address range specified - $from = ip2long(trim(substr($network, 0, $d))); - $to = ip2long(trim(substr($network, $d + 1))); - $ip = ip2long($ip); - return ($ip >= $from && $ip <= $to); - } + return false; } function request_headers() Index: kernel/processors/main_processor.php =================================================================== --- kernel/processors/main_processor.php (revision 13128) +++ kernel/processors/main_processor.php (working copy) @@ -825,10 +825,14 @@ if (!$ssl) { // not in admin or admin ssl url is empty - $ssl = $this->Application->ConfigValue('SSL_URL'); + $ssl_url = $this->Application->siteDomainField('SSLUrl'); + $ssl = $ssl_url !== false ? $ssl_url : $this->Application->ConfigValue('SSL_URL'); } - if (!$ssl) return; //SSL URL is not set - no way to require SSL + if (!$ssl) { + // SSL URL is not set - no way to require SSL + return; + } $require = false; Index: units/admin/admin_tag_processor.php =================================================================== --- units/admin/admin_tag_processor.php (revision 13128) +++ units/admin/admin_tag_processor.php (working copy) @@ -147,7 +147,6 @@ return ''; } - if (array_key_exists('parent', $params) && $params['parent']) { do { $section = $section_data['parent']; @@ -175,13 +174,15 @@ break; case 'label': - $res = $section_data['label']; - if ($section != 'in-portal:root') { + if ($section && ($section != 'in-portal:root')) { // don't translate label for top section, because it's already translated $no_editing = array_key_exists('no_editing', $params) ? $params['no_editing'] : false; - $res = $this->Application->Phrase($res, !$no_editing); + $res = $this->Application->Phrase($section_data['label'], !$no_editing); } + else { + $res = ''; + } break; default: Index: units/helpers/helpers_config.php =================================================================== --- units/helpers/helpers_config.php (revision 13128) +++ units/helpers/helpers_config.php (working copy) @@ -58,5 +58,6 @@ Array ('class' => 'kXMLHelper', 'pseudo' => 'kXMLHelper', 'file' => 'xml_helper.php', 'build_event' => '', 'require_classes' => 'kHelper'), Array ('class' => 'kCatDBItemExportHelper', 'pseudo' => 'CatItemExportHelper', 'file' => 'cat_dbitem_export_helper.php', 'build_event' => '', 'require_classes' => 'kHelper'), Array ('class' => 'EmailMessageHelper', 'pseudo' => 'EmailMessageHelper', 'file' => 'email_message_helper.php', 'build_event' => '', 'require_classes' => 'kHelper'), + Array ('class' => 'SiteHelper', 'pseudo' => 'SiteHelper', 'file' => 'site_helper.php', 'build_event' => '', 'require_classes' => 'kHelper'), ), ); \ No newline at end of file Index: units/helpers/mod_rewrite_helper.php =================================================================== --- units/helpers/mod_rewrite_helper.php (revision 13128) +++ units/helpers/mod_rewrite_helper.php (working copy) @@ -45,6 +45,20 @@ var $_templateAliases = null; /** + * Domain-based primary language id + * + * @var int + */ + var $primaryLanguageId = false; + + /** + * Domain-based primary theme id + * + * @var int + */ + var $primaryThemeId = false; + + /** * Constructor of kModRewriteHelper class * * @return kModRewriteHelper @@ -54,6 +68,12 @@ parent::kHelper(); $this->HTTPQuery =& $this->Application->recallObject('HTTPQuery'); + + // domain based primary language + $this->primaryLanguageId = $this->Application->siteDomainField('PrimaryLanguageId'); + + // domain based primary theme + $this->primaryThemeId = $this->Application->siteDomainField('PrimaryThemeId'); } function processRewriteURL() @@ -329,8 +349,12 @@ } // add language - $default_language_id = $this->Application->GetDefaultLanguageId(); - if ($processed_params['m_lang'] && ($processed_params['m_lang'] != $default_language_id)) { + if (!$this->primaryLanguageId) { + // when domain-based language not found -> use site-wide language + $this->primaryLanguageId = $this->Application->GetDefaultLanguageId(); + } + + if ($processed_params['m_lang'] && ($processed_params['m_lang'] != $this->primaryLanguageId)) { $language_name = $this->Application->getCache('language_names', $processed_params['m_lang']); if ($language_name === false) { $sql = 'SELECT PackName @@ -345,8 +369,12 @@ } // add theme - $default_theme_id = $this->Application->GetDefaultThemeId(true); - if ($processed_params['m_theme'] && ($processed_params['m_theme'] != $default_theme_id)) { + if (!$this->primaryThemeId) { + // when domain-based language not found -> use site-wide language + $this->primaryThemeId = $this->Application->GetDefaultThemeId(true); + } + + if ($processed_params['m_theme'] && ($processed_params['m_theme'] != $this->primaryThemeId)) { $theme_name = $this->Application->getCache('theme_names', $processed_params['m_theme']); if ($theme_name === false) { $sql = 'SELECT Name @@ -454,6 +482,10 @@ // language was found by pack name array_shift($url_parts); } + elseif ($this->primaryLanguageId) { + // use domain-based primary language instead of site-wide primary language + $vars['m_lang'] = $this->primaryLanguageId; + } return true; } @@ -498,6 +530,10 @@ // theme was found by name array_shift($url_parts); } + elseif ($this->primaryThemeId) { + // use domain-based primary theme instead of site-wide primary theme + $vars['m_theme'] = $this->primaryThemeId; + } return true; } @@ -976,17 +1012,31 @@ } /** - * Sets default parsed values before actual url parsing + * Sets default parsed values before actual url parsing (only, for empty url) * * @param Array $vars */ function _setDefaultValues(&$vars) { - $defaults = Array ('m_cat_id' => 0, 'm_cat_page' => 1, 'm_opener' => 's', 't' => 'index'); + $defaults = Array ( + 'm_cat_id' => 0, // no category + 'm_cat_page' => 1, // first category page + 'm_opener' => 's', // stay on same page + 't' => 'index' // main site page + ); + if ($this->primaryLanguageId) { + // domain-based primary language + $defaults['m_lang'] = $this->primaryLanguageId; + } + + if ($this->primaryThemeId) { + // domain-based primary theme + $defaults['m_theme'] = $this->primaryThemeId; + } + foreach ($defaults as $default_key => $default_value) { - // bug: null is never returned - if ($this->HTTPQuery->Get($default_key) == null) { + if ($this->HTTPQuery->Get($default_key) === false) { $vars[$default_key] = $default_value; } } Index: units/helpers/site_helper.php =================================================================== --- units/helpers/site_helper.php (revision 0) +++ units/helpers/site_helper.php (revision 0) @@ -0,0 +1,44 @@ +Application->siteDomainField($country_prefix . 'Country'); + + if ($iso_format && !$country) { + $country = 'USA'; + } + + if (!$iso_format && strlen($country)) { + return $this->getCountryId($country); + } + + return $country; + } + + /** + * Returns country id based on it's ISO code + * + * @param string $iso_code + * @return int + */ + function getCountryId($iso_code) + { + static $cache = null; + + if (!isset($cache)) { + $sql = 'SELECT DestId, DestAbbr + FROM ' . TABLE_PREFIX . 'StdDestinations + WHERE DestType = 1'; + $cache = $this->Conn->GetCol($sql, 'DestAbbr'); + } + + return $cache[$iso_code]; + } + } Index: units/languages/languages_event_handler.php =================================================================== --- units/languages/languages_event_handler.php (revision 13151) +++ units/languages/languages_event_handler.php (working copy) @@ -160,12 +160,28 @@ */ function SetCustomQuery(&$event) { - if ($event->Special == 'enabled') { - $object =& $event->getObject(); - /* @var $object kDBList */ + $object =& $event->getObject(); + /* @var $object kDBList */ - $object->addFilter('enabled_filter', '%1$s.Enabled = 1'); + if (in_array($event->Special, Array ('enabled', 'selected', 'available'))) { + $object->addFilter('enabled_filter', '%1$s.Enabled = ' . STATUS_ACTIVE); } + + // site domain language picker + if ($event->Special == 'selected' || $event->Special == 'available') { + $edit_picker_helper =& $this->Application->recallObject('EditPickerHelper'); + /* @var $edit_picker_helper EditPickerHelper */ + + $edit_picker_helper->applyFilter($event, 'Languages'); + } + + // apply domain-based language filtering + $languages = $this->Application->siteDomainField('Languages'); + + if (strlen($languages)) { + $languages = explode('|', substr($languages, 1, -1)); + $object->addFilter('domain_filter', '%1$s.LanguageId IN (' . implode(',', $languages) . ')'); + } } /** Index: units/site_domains/site_domain_eh.php =================================================================== --- units/site_domains/site_domain_eh.php (revision 0) +++ units/site_domains/site_domain_eh.php (revision 0) @@ -0,0 +1,205 @@ + Array ('self' => true), + ); + + $this->permMapping = array_merge($this->permMapping, $permissions); + } + + /** + * Returns ID of site domain, that matches current url + * + * @param kEvent $event + */ + function getPassedID(&$event) + { + if ($event->Special == 'current') { + if ($this->Application->isAdmin) { + $event->setEventParam('raise_warnings', 0); + } + else { + if (PROTOCOL == 'https://') { + return $this->querySiteDomain('SSLUrl', rtrim($this->Application->BaseURL(), '/')); + } + + return $this->querySiteDomain('DomainName', $_SERVER['HTTP_HOST']); + } + } + + return parent::getPassedID($event); + } + + function querySiteDomain($field, $value) + { + $site_domains = $this->getSiteDomains(); + $name_fields = Array ('DomainName', 'SSLUrl'); + + // 1. try to match visited domain to any of existing + foreach ($site_domains as $id => $site_domain) { + if (in_array($field, $name_fields) && $site_domain[$field . 'UsesRegExp']) { + if (preg_match('/^' . $site_domain[$field] . '$/', $value)) { + return $id; + } + } + elseif ($site_domain[$field] == $value) { + return $id; + } + + } + + // 2. try to match domain settings based on visitor's IP address + foreach ($site_domains as $id => $site_domain) { + if (ipMatch($site_domain['DomainIPRange'], "\n")) { + if ($site_domain['RedirectOnIPMatch']) { + $this->Application->Redirect('external:http://' . $site_domain['DomainName'] . $_SERVER['REQUEST_URI']); + } + + return $id; + } + } + + return false; + } + + /** + * Load item if id is available + * + * @param kEvent $event + */ + function LoadItem(&$event) + { + $object =& $event->getObject(); + /* @var $object kDBItem */ + + $id = (int)$this->getPassedID($event); + + if ($object->isLoaded() && ($object->GetID() == $id)) { + // object is already loaded by same id + return ; + } + + $object->setID($id); + $site_domains = $this->getSiteDomains(); + + if (array_key_exists($id, $site_domains)) { + $object->Loaded = true; + $object->SetDBFieldsFromHash($site_domains[$id]); + + $actions =& $this->Application->recallObject('kActions'); + $actions->Set($event->Prefix_Special.'_id', $object->GetID() ); + } + else { + $object->Loaded = false; + } + } + + function getSiteDomains() + { + static $cache = null; + + if (!isset($cache)) { + $sql = 'SELECT Data + FROM ' . TABLE_PREFIX . 'Cache + WHERE VarName = "domains_parsed"'; + $cache = $this->Conn->GetOne($sql); + + if ($cache) { + $cache = unserialize($cache); + } + else { + $id_field = $this->Application->getUnitOption($this->Prefix, 'IDField'); + $table_name = $this->Application->getUnitOption($this->Prefix, 'TableName'); + + $sql = 'SELECT * + FROM ' . $table_name . ' + ORDER BY Priority DESC'; + $cache = $this->Conn->Query($sql, $id_field); + + $fields_hash = Array ( + 'VarName' => 'domains_parsed', + 'Data' => serialize($cache), + 'Cached' => adodb_mktime(), + ); + + $this->Conn->doInsert($fields_hash, TABLE_PREFIX . 'Cache'); + } + } + + return $cache; + } + + /** + * Removes In-Commerce related fields, when it's not installed + * + * @param kEvent $event + */ + function OnAfterConfigRead(&$event) + { + parent::OnAfterConfigRead($event); + + if (!$this->Application->isModuleEnabled('In-Commerce')) { + $remove_fields = Array ( + 'BillingCountry', 'ShippingCountry', + 'PrimaryCurrencyId', 'Currencies', + 'PrimaryPaymentTypeId', 'PaymentTypes' + ); + + // remove field definitions + $fields = $this->Application->getUnitOption($event->Prefix, 'Fields'); + + foreach ($remove_fields as $remove_field) { + unset($fields[$remove_field]); + } + + $this->Application->setUnitOption($event->Prefix, 'Fields', $fields); + + // remove grid columns + $grids = $this->Application->getUnitOption($event->Prefix, 'Grids'); + + foreach ($grids as $grid_name => $grid_info) { + foreach ($remove_fields as $remove_field) { + if (array_key_exists($remove_field, $grid_info['Fields'])) { + unset($grids[$grid_name]['Fields'][$remove_field]); + } + } + } + + $this->Application->setUnitOption($event->Prefix, 'Grids', $grids); + } + } + + /** + * Delete cached information about site domains + * + * @param kEvent $event + */ + function OnSave(&$event) + { + parent::OnSave($event); + + if ($event->status == erSUCCESS) { + $this->_deleteCache(); + } + } + + /** + * Deletes cached information about site domains + */ + function _deleteCache() + { + $sql = 'DELETE FROM ' . TABLE_PREFIX . 'Cache + WHERE VarName = "domains_parsed"'; + $this->Conn->Query($sql); + } + } \ No newline at end of file Index: units/site_domains/site_domains_config.php =================================================================== --- units/site_domains/site_domains_config.php (revision 0) +++ units/site_domains/site_domains_config.php (revision 0) @@ -0,0 +1,180 @@ + 'site-domain', + 'ItemClass' => Array ('class' => 'kDBItem', 'file' => '', 'build_event' => 'OnItemBuild'), + 'ListClass' => Array ('class' => 'kDBList', 'file' => '', 'build_event' => 'OnListBuild'), + 'EventHandlerClass' => Array ('class' => 'SiteDomainEventHandler', 'file' => 'site_domain_eh.php', 'build_event' => 'OnBuild'), + 'TagProcessorClass' => Array ('class' => 'kDBTagProcessor', 'file' => '', 'build_event' => 'OnBuild'), + + 'AutoLoad' => true, + + 'QueryString' => Array ( + 1 => 'id', + 2 => 'Page', + 3 => 'event', + 4 => 'mode', + ), + + 'IDField' => 'DomainId', + + 'TableName' => TABLE_PREFIX . 'SiteDomains', + + 'TitleField' => 'DomainName', + + 'TitlePresets' => Array ( + 'default' => Array ( + 'new_status_labels' => Array ('site-domain' => '!la_title_AddingSiteDomain!'), + 'edit_status_labels' => Array ('site-domain' => '!la_title_EditingSiteDomain!'), + ), + + 'site_domain_list' => Array ( + 'prefixes' => Array ('site-domain_List'), 'format' => "!la_title_SiteDomains!", + 'toolbar_buttons' => Array ('new_item', 'edit', 'delete', 'view', 'dbl-click'), + ), + + 'site_domain_edit' => Array ( + 'prefixes' => Array ('site-domain'), 'format' => "#site-domain_status# '#site-domain_titlefield#'", + 'toolbar_buttons' => Array ('select', 'cancel', 'reset_edit', 'prev', 'next'), + ), + ), + + 'PermSection' => Array('main' => 'in-portal:site_domains'), + + 'Sections' => Array ( + 'in-portal:site_domains' => Array ( + 'parent' => 'in-portal:website_setting_folder', + 'icon' => 'site_domain', + 'label' => 'la_title_SiteDomains', + 'url' => Array('t' => 'site_domains/site_domain_list', 'pass' => 'm'), + 'permissions' => Array('view', 'add', 'edit', 'delete'), + 'priority' => 7, + 'type' => stTREE, + ), + ), + + 'ListSQLs' => Array ( + '' => ' SELECT %1$s.* %2$s FROM %1$s', + ), + + 'ListSortings' => Array ( + '' => Array ( + 'Sorting' => Array ('Priority' => 'desc', 'DomainName' => 'asc'), + ) + ), + + 'Fields' => Array ( + 'DomainId' => Array ('type' => 'int', 'not_null' => 1, 'default' => 0), + 'DomainName' => Array ('type' => 'string', 'max_len' => 255, 'not_null' => 1, 'required' => 1, 'default' => ''), + 'DomainNameUsesRegExp' => Array ( + 'type' => 'int', + 'formatter' => 'kOptionsFormatter', 'options' => Array (1 => 'la_Yes', 0 => 'la_No'), 'use_phrases' => 1, + 'not_null' => 1, 'default' => 0 + ), + 'SSLUrl' => Array ('type' => 'string', 'max_len' => 255, 'not_null' => 1, 'default' => ''), + 'SSLUrlUsesRegExp' => Array ( + 'type' => 'int', + 'formatter' => 'kOptionsFormatter', 'options' => Array (1 => 'la_Yes', 0 => 'la_No'), 'use_phrases' => 1, + 'not_null' => 1, 'default' => 0 + ), + 'AdminEmail' => Array ('type' => 'string', 'max_len' => 255, 'not_null' => 1, 'default' => ''), + 'Country' => Array ( + 'type' => 'string', 'max_len' => 3, + 'formatter' => 'kOptionsFormatter', + 'options_sql' => ' SELECT %1$s + FROM ' . TABLE_PREFIX . 'StdDestinations + LEFT JOIN ' . TABLE_PREFIX . 'Phrase p ON p.Phrase = ' . TABLE_PREFIX . 'StdDestinations.DestName + WHERE DestType = 1 + ORDER BY l%2$s_Translation', + 'option_key_field' => 'DestAbbr', 'option_title_field' => 'l%2$s_Translation', + 'not_null' => 1, 'default' => '' + ), + 'BillingCountry' => Array ( + 'type' => 'string', 'max_len' => 3, + 'formatter' => 'kOptionsFormatter', + 'options_sql' => ' SELECT %1$s + FROM ' . TABLE_PREFIX . 'StdDestinations + LEFT JOIN ' . TABLE_PREFIX . 'Phrase p ON p.Phrase = ' . TABLE_PREFIX . 'StdDestinations.DestName + WHERE DestType = 1 + ORDER BY l%2$s_Translation', + 'option_key_field' => 'DestAbbr', 'option_title_field' => 'l%2$s_Translation', + 'not_null' => 1, 'default' => '' + ), + 'ShippingCountry' => Array ( + 'type' => 'string', 'max_len' => 3, + 'formatter' => 'kOptionsFormatter', + 'options_sql' => ' SELECT %1$s + FROM ' . TABLE_PREFIX . 'StdDestinations + LEFT JOIN ' . TABLE_PREFIX . 'Phrase p ON p.Phrase = ' . TABLE_PREFIX . 'StdDestinations.DestName + WHERE DestType = 1 + ORDER BY l%2$s_Translation', + 'option_key_field' => 'DestAbbr', 'option_title_field' => 'l%2$s_Translation', + 'not_null' => 1, 'default' => '' + ), + 'PrimaryLanguageId' => Array ( + 'type' => 'int', + 'formatter' => 'kOptionsFormatter', 'options_sql' => 'SELECT %s FROM ' . TABLE_PREFIX . 'Language WHERE Enabled = 1 ORDER BY PackName ASC', 'option_key_field' => 'LanguageId', 'option_title_field' => 'PackName', + 'not_null' => 1, 'default' => 0 + ), + 'Languages' => Array ( + 'type' => 'string', 'max_len' => 255, + 'formatter' => 'kOptionsFormatter', 'options_sql' => 'SELECT %s FROM ' . TABLE_PREFIX . 'Language WHERE Enabled = 1 ORDER BY PackName ASC', 'option_key_field' => 'LanguageId', 'option_title_field' => 'PackName', + 'not_null' => 1, 'default' => '' + ), + 'PrimaryThemeId' => Array ( + 'type' => 'int', + 'formatter' => 'kOptionsFormatter', 'options_sql' => 'SELECT %s FROM ' . TABLE_PREFIX . 'Theme WHERE Enabled = 1 ORDER BY Name ASC', 'option_key_field' => 'ThemeId', 'option_title_field' => 'Name', + 'not_null' => 1, 'default' => 0 + ), + 'Themes' => Array ( + 'type' => 'string', 'max_len' => 255, + 'formatter' => 'kOptionsFormatter', 'options_sql' => 'SELECT %s FROM ' . TABLE_PREFIX . 'Theme WHERE Enabled = 1 ORDER BY Name ASC', 'option_key_field' => 'ThemeId', 'option_title_field' => 'Name', + 'not_null' => 1, 'default' => '' + ), + 'PrimaryCurrencyId' => Array ( + 'type' => 'int', + 'formatter' => 'kOptionsFormatter', 'options_sql' => 'SELECT %s FROM ' . TABLE_PREFIX . 'Currencies WHERE Status = 1 ORDER BY ISO', 'option_key_field' => 'CurrencyId', 'option_title_field' => 'Name', 'use_phrases' => 1, + 'not_null' => 1, 'default' => 0 + ), + 'Currencies' => Array ( + 'type' => 'string', 'max_len' => 255, + 'formatter' => 'kOptionsFormatter', 'options_sql' => 'SELECT %s FROM ' . TABLE_PREFIX . 'Currencies WHERE Status = 1 ORDER BY ISO', 'option_key_field' => 'CurrencyId', 'option_title_field' => 'Name', 'use_phrases' => 1, + 'not_null' => 1, 'default' => '' + ), + 'PrimaryPaymentTypeId' => Array ( + 'type' => 'int', + 'formatter' => 'kOptionsFormatter', 'options_sql' => 'SELECT %s FROM ' . TABLE_PREFIX . 'PaymentTypes WHERE Status = 1 ORDER BY Name ASC', 'option_key_field' => 'PaymentTypeId', 'option_title_field' => 'Name', + 'not_null' => 1, 'default' => 0 + ), + 'PaymentTypes' => Array ( + 'type' => 'string', 'max_len' => 255, + 'formatter' => 'kOptionsFormatter', 'options_sql' => 'SELECT %s FROM ' . TABLE_PREFIX . 'PaymentTypes WHERE Status = 1 ORDER BY Name ASC', 'option_key_field' => 'PaymentTypeId', 'option_title_field' => 'Name', + 'not_null' => 1, 'default' => '' + ), + 'DomainIPRange' => Array ('type' => 'string', 'not_null' => 1, 'default' => NULL), + 'RedirectOnIPMatch' => Array ( + 'type' => 'int', + 'formatter' => 'kOptionsFormatter', 'options' => Array (1 => 'la_Yes', 0 => 'la_No'), 'use_phrases' => 1, + 'not_null' => 1, 'default' => 0 + ), + 'Priority' => Array ('type' => 'int', 'not_null' => 1, 'default' => 0), + ), + + 'Grids' => Array ( + 'Default' => Array ( + 'Icons' => Array ('default' => 'icon16_item.png'), + 'Fields' => Array ( + 'DomainId' => Array ('title' => 'la_col_Id', 'data_block' => 'grid_checkbox_td', 'filter_block' => 'grid_range_filter', 'width' => 70, ), + 'DomainName' => Array ('title' => 'la_col_DomainName', 'filter_block' => 'grid_like_filter', 'width' => 250, ), + 'SSLUrl' => Array ('title' => 'la_col_SSLUrl', 'filter_block' => 'grid_like_filter', 'width' => 250, ), + 'Country' => Array ('title' => 'la_col_Country', 'filter_block' => 'grid_options_filter', 'width' => 250, ), + 'BillingCountry' => Array ('title' => 'la_col_BillingCountry', 'filter_block' => 'grid_options_filter', 'width' => 250, ), + 'ShippingCountry' => Array ('title' => 'la_col_ShippingCountry', 'filter_block' => 'grid_options_filter', 'width' => 250, ), + 'PrimaryLanguageId' => Array ('title' => 'la_col_Language', 'filter_block' => 'grid_options_filter', 'width' => 250, ), + 'PrimaryThemeId' => Array ('title' => 'la_col_Theme', 'filter_block' => 'grid_options_filter', 'width' => 250, ), + 'PrimaryCurrencyId' => Array ('title' => 'la_col_Currency', 'filter_block' => 'grid_options_filter', 'width' => 250, ), + 'PrimaryPaymentTypeId' => Array ('title' => 'la_col_PaymentType', 'filter_block' => 'grid_options_filter', 'width' => 250, ), + 'Priority' => Array ('title' => 'la_col_Priority', 'filter_block' => 'grid_range_filter', 'width' => 70, ), + ), + ), + ), + ); \ No newline at end of file Index: units/themes/themes_eh.php =================================================================== --- units/themes/themes_eh.php (revision 13128) +++ units/themes/themes_eh.php (working copy) @@ -153,13 +153,28 @@ { parent::SetCustomQuery($event); - if ($event->Special == 'enabled' || !$this->Application->isAdminUser) { + $object =& $event->getObject(); + /* @var $object kDBList */ + + if (in_array($event->Special, Array ('enabled', 'selected', 'available')) || !$this->Application->isAdminUser) { // "enabled" special or Front-End + $object->addFilter('enabled_filter', '%1$s.Enabled = ' . STATUS_ACTIVE); + } - $object =& $event->getObject(); - /* @var $object kDBList */ + // site domain theme picker + if ($event->Special == 'selected' || $event->Special == 'available') { + $edit_picker_helper =& $this->Application->recallObject('EditPickerHelper'); + /* @var $edit_picker_helper EditPickerHelper */ - $object->addFilter('enabled_filter', '%1$s.Enabled = 1'); + $edit_picker_helper->applyFilter($event, 'Themes'); } + + // apply domain-based theme filtering + $themes = $this->Application->siteDomainField('Themes'); + + if (strlen($themes)) { + $themes = explode('|', substr($themes, 1, -1)); + $object->addFilter('domain_filter', '%1$s.ThemeId IN (' . implode(',', $themes) . ')'); + } } } Index: units/users/users_event_handler.php =================================================================== --- units/users/users_event_handler.php (revision 13128) +++ units/users/users_event_handler.php (working copy) @@ -1581,7 +1581,15 @@ parent::OnAfterConfigRead($event); // 1. arrange user registration countries - $first_country = $this->Application->ConfigValue('User_Default_Registration_Country'); + $site_helper =& $this->Application->recallObject('SiteHelper'); + /* @var $site_helper SiteHelper */ + + $first_country = $site_helper->getDefaultCountry('', false); + + if ($first_country === false) { + $first_country = $this->Application->ConfigValue('User_Default_Registration_Country'); + } + if ($first_country) { // update user country dropdown sql $fields = $this->Application->getUnitOption($event->Prefix, 'Fields'); @@ -1625,7 +1633,6 @@ $this->Application->setUnitOption($event->Prefix, 'EditTabPresets', $edit_tab_presets); } } - } /**