. * */ namespace Vvveb\System; use function Vvveb\__; class Sites { private static $sites = null; private static $host_matches = []; const HOST_REGEX = '@(?https://|http://|//|^)(?.*?)?\.?(?[^\.]+)\.(?[^\.]+|[^\.]{2,3}\.[^\.]{2,3})((?/.*)|$)@'; private static $states; /* private static $states = [ 'live' => ['name' => 'Live', 'template' => 'index.html', 'icon' => 'la-broadcast-tower'], 'maintenance' => ['name' => 'Maintenance', 'template' => 'index.maintenance.html', 'icon' => 'la-wrench'], 'coming-soon' => ['name' => 'Coming soon', 'template' => 'index.coming-soon.html', 'icon' => 'la-clock'], ]; */ public static function getStates() { static :: $states = [ 'live' => ['name' => __('Live'), 'template' => 'index.html', 'icon' => 'la-broadcast-tower'], 'maintenance' => ['name' => __('Maintenance'), 'template' => 'index.maintenance.html', 'icon' => 'la-wrench'], 'coming-soon' => ['name' => __('Coming soon'), 'template' => 'index.coming-soon.html', 'icon' => 'la-clock'], ]; return static :: $states; } public static function getDefault() { $sites = self :: getSites(); return current($sites); } public static function getSites() { if (! self :: $sites) { self :: $sites = \Vvveb\config('sites'); foreach (self::$sites as &$site) { $site['url'] = self :: url($site['host']) . (V_SUBDIR_INSTALL ? V_SUBDIR_INSTALL : '') . ($site['path'] ?? '' ? '/' . $site['path'] : ''); } return self :: $sites; } return self :: $sites; } public static function getSiteByKey($site_key) { $sites = self :: getSites(); $site_key = self :: siteKey($site_key); if (isset($sites[$site_key])) { $site = $sites[$site_key]; $site['key'] = $site_key; return $site; } return false; } public static function getSiteById($site_id) { $sites = self :: getSites(); foreach ($sites as $site_key => $site) { if ($site['id'] == $site_id) { $site['key'] = $site_key; return $site; } } } public static function getTheme($site = false) { $data = self :: getSiteData($site); if ($data) { return $data['theme']; } return 'default'; } public static function setTheme($site, $theme, $template = '') { if ($template) { self :: setSiteData($site, 'template', $template); } return self :: setSiteData($site, 'theme', $theme); } public static function urlSplit($url = null) { $url = $url ?? $_SERVER['HTTP_HOST'] ?? ''; $host = $host ?? self :: getHost(); $host_matches = self :: $host_matches[$host] ?? []; if (preg_match(self :: HOST_REGEX, $url, $matches)) { if (($host_matches || preg_match(self :: HOST_REGEX, $host, $host_matches))//check is not ip && ! is_numeric($host_matches['domain'] ?? null)) { self :: $host_matches[$host] = $host_matches; $has_subdomain = ! empty($host_matches['subdomain']) || ($matches['subdomain'] != '*'); $has_tld = ! empty($host_matches['tld']) || ($matches['tld'] != '*'); return $matches; } //if host is ip number, localhost or does not have tld remove tld and subdomain if (is_numeric($host_matches['domain'] ?? null) || $host == 'localhost' || (strpos($host, '.') === false)) { $matches['domain'] = $host; $matches['subdomain'] = $matches['tld'] = $matches['prefix'] = ''; } if ($host == 'localhost') { $matches['domain'] = 'localhost'; $matches['subdomain'] = $matches['tld'] = $matches['prefix'] = ''; } return $matches; } return []; } public static function url($url, $host = null) { $host = $host ?? self :: getHost(); $hasPort = strpos($host, ':') ?: null; $hostWp = substr($host, 0, strpos($host, ':') ?: null); $host_matches = self :: $host_matches[$host] ?? []; if (preg_match(self :: HOST_REGEX, $url, $matches)) { if (($host_matches || preg_match(self :: HOST_REGEX, $host, $host_matches))//check is not ip && ! is_numeric($host_matches['domain'] ?? null)) { self :: $host_matches[$host] = $host_matches; $subdomain = str_replace('*', $host_matches['subdomain'], $matches['subdomain']); $domain = str_replace('*', $host_matches['domain'], $matches['domain']); $tld = str_replace('*', $host_matches['tld'], $matches['tld']); return $matches['prefix'] . $subdomain . ($subdomain ? '.' : '') . $domain . ($tld ? '.' : '') . $tld . ($matches['path'] ?? ''); } //if host is ip number, localhost or does not have tld remove tld and subdomain if (! ($matches['prefix'] || ($matches['tld'] && $matches['tld'] !== '*')) && (is_numeric($host_matches['domain'] ?? null) || $hostWp == 'localhost' || (strpos($hostWp, '.') === false))) { $matches['domain'] = $host; $matches['subdomain'] = $matches['tld'] = $matches['prefix'] = ''; } $url = ($matches['prefix'] ? $matches['prefix'] : '') . (! empty($matches['subdomain']) ? $matches['subdomain'] . '.' : '') . ($matches['domain'] ?? '') . (! empty($matches['tld']) ? '.' . $matches['tld'] : '') . ($matches['path'] ?? ''); } return $url; } public static function siteKey($site_url = false) { return str_replace('.', ' ',$site_url); } public static function setSiteDataById($site_id, $name, $value) { $site = self :: getSiteById($site_id); if ($site && ($site['id'] == $site_id)) { $key = "sites.{$site['key']}"; //key has changed replace site if (isset($value['key']) && ($value['key'] != $site['key'])) { $config = \Vvveb\getConfig($key); if ($config) { $value += $config; $config = \Vvveb\unsetConfig($key); $key = "sites.{$value['key']}"; } } if ($name) { $key .= ".$name"; } return \Vvveb\setConfig($key, $value); } return false; } public static function setSiteDataByKey($site_key, $name, $value) { $site = self :: getSiteByKey($site_key); $site_key = self :: siteKey($site_key); if ($site && ($site['key'] == $site_key)) { $key = "sites.{$site['key']}"; if ($name) { $key .= ".$name"; } return \Vvveb\setConfig($key, $value); } return false; } public static function setSiteData($site, $name, $value) { if (is_int($site)) { return self :: setSiteDataById($site, $name, $value); } else { return self :: setSiteDataByKey($site, $name, $value); } } public static function getHost() { $host = $_SERVER['HTTP_HOST'] ?? 'localhost'; return $host; } public static function getSiteData($site_url = false) { if (is_int($site_url)) { return self :: getSiteById($site_url); } if (! $site_url) { $host = $_SERVER['HTTP_HOST'] ?? 'localhost'; } $cacheDriver = Cache :: getInstance(); $cacheKey = $host; if ($result = $cacheDriver->get('site', $cacheKey)) { return $result; } else { $host = self :: siteKey($host); $first = strpos($host, ' '); $last = strrpos($host, ' '); $subdomain_wildcard = '* ' . substr($host, $first); $tld_wildcard = substr($host, 0, $last) . ' *'; $domain_wildcard = substr($host, 0, $first) . ' * *'; $full_wildcard = '* ' . trim(substr($host, $first, $last - $first)) . ' *'; $result = \Vvveb\config("sites.$host", null) ?? \Vvveb\config("sites.$subdomain_wildcard", null) ?? \Vvveb\config("sites.$domain_wildcard", null) ?? \Vvveb\config("sites.$full_wildcard", null) ?? \Vvveb\config("sites.$tld_wildcard", null) ?? \Vvveb\config('sites.* * *', null); if ($result) { $result['host'] = self :: url($result['host']); } else { if (APP !== 'app') { //if site does not exist use fallback for admin, cli etc $result = [ 'host' => 'localhost', 'theme' => 'landing', 'template' => '', 'id' => 1, 'state' => 'live', ]; } } $cacheDriver->set('site', $cacheKey, $result); } return $result; } public static function saveSite($site) { $key = self :: siteKey(trim($site['key'] ?? $site['host'])); unset($site['key']); $return = \Vvveb\setConfig("sites.$key", $site); } public static function deleteSite($site) { $key = self :: siteKey(trim($site['key'] ?? $site['host'])); $return = \Vvveb\unsetConfig("sites.$key", $site); } }