PageRenderTime 53ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/wa-system/routing/waRouting.class.php

http://github.com/webasyst/webasyst-framework
PHP | 783 lines | 658 code | 86 blank | 39 comment | 214 complexity | e495b7885385dd7fcf5cb4e340846661 MD5 | raw file
Possible License(s): LGPL-3.0, CC-BY-3.0, BSD-3-Clause, MIT
  1. <?php
  2. class waRouting
  3. {
  4. /**
  5. * @var waSystem
  6. */
  7. protected $system;
  8. protected $routes = array();
  9. protected $domain;
  10. protected $route;
  11. protected $root_url;
  12. protected $aliases = array();
  13. protected $url_placeholders = array();
  14. public function __construct(waSystem $system, $routes = array())
  15. {
  16. $this->system = $system;
  17. if (!$routes) {
  18. $routes = $this->system->getConfig()->getConfigFile('routing');
  19. if (!is_array($routes)) {
  20. waLog::log("Invalid or missed routing config file");
  21. $routes = array();
  22. }
  23. }
  24. $this->setRoutes($routes);
  25. }
  26. public function setRoutes($routes)
  27. {
  28. foreach ($routes as $domain => $domain_routes) {
  29. if (is_array($domain_routes)) {
  30. $this->routes[$domain] = $this->formatRoutes($domain_routes, false);
  31. } else {
  32. $this->aliases[$domain] = $domain_routes;
  33. $this->routes[$domain] = isset($routes[$domain_routes]) ? $routes[$domain_routes] : array();
  34. }
  35. }
  36. }
  37. public function isAlias($domain)
  38. {
  39. return isset($this->aliases[$domain]) ? $this->aliases[$domain] : false;
  40. }
  41. /**
  42. * @return array[string] mirror domain => actual domain mirror points to
  43. * @since 1.14.5
  44. */
  45. public function getAliases()
  46. {
  47. return $this->aliases;
  48. }
  49. public function getDomains()
  50. {
  51. return array_diff(array_keys($this->routes), array_keys($this->aliases));
  52. }
  53. public function setRoute($route, $domain = null)
  54. {
  55. $this->route = $route;
  56. if ($domain !== null) {
  57. $this->domain = $domain;
  58. }
  59. }
  60. public function getRoute($name = null)
  61. {
  62. if ($name) {
  63. return isset($this->route[$name]) ? $this->route[$name] : null;
  64. }
  65. return $this->route;
  66. }
  67. protected function formatRoutes($routes, $app_id = false)
  68. {
  69. $result = array();
  70. $routes[] = false;
  71. $keys = array_keys($routes);
  72. $n = end($keys);
  73. unset($keys);
  74. unset($routes[$n]);
  75. foreach ($routes as $r_id => $r) {
  76. $key = false;
  77. if (!is_array($r)) {
  78. $r_parts = explode('/', $r);
  79. $r = array('url' => $r_id);
  80. if ($app_id) {
  81. $r['module'] = $r_parts[0];
  82. if (isset($r_parts[1])) {
  83. $r['action'] = $r_parts[1];
  84. }
  85. } else {
  86. $r['app'] = $r_parts[0];
  87. if (isset($r_parts[1])) {
  88. $r['module'] = $r_parts[1];
  89. }
  90. }
  91. } elseif (!isset($r['url'])) {
  92. $r['url'] = $r_id;
  93. } else {
  94. $key = true;
  95. }
  96. if ($app_id && empty($r['app'])) {
  97. $r['app'] = $app_id;
  98. }
  99. if ($key) {
  100. $result[$r_id] = $r;
  101. } else {
  102. $result[$n++] = $r;
  103. }
  104. }
  105. return $result;
  106. }
  107. public function getByApp($app_id, $domain = null)
  108. {
  109. $result = array();
  110. foreach ($this->routes as $d => $routes) {
  111. if (isset($this->aliases[$d])) {
  112. continue;
  113. }
  114. foreach ($routes as $r_id => $r) {
  115. if (isset($r['app']) && $r['app'] == $app_id) {
  116. $result[$d][$r_id] = $r;
  117. }
  118. }
  119. }
  120. if ($domain) {
  121. return isset($result[$domain]) ? $result[$domain] : array();
  122. }
  123. return $result;
  124. }
  125. public function getRoutes($domain = null)
  126. {
  127. $domain = $this->getDomain($domain, true);
  128. if (isset($this->routes[$domain])) {
  129. return $this->routes[$domain];
  130. }
  131. if (isset($this->routes['default']) && $this->routes['default']) {
  132. return $this->routes['default'];
  133. }
  134. return array();
  135. }
  136. public function getDomain($domain = null, $check = false, $return_alias = true)
  137. {
  138. if ($domain) {
  139. return $domain;
  140. }
  141. if ($this->domain === null || !$return_alias) {
  142. $this->domain = $this->getDomainNoAlias();
  143. if ($this->domain === null) {
  144. return null;
  145. }
  146. }
  147. if ($check && !isset($this->routes[$this->domain])) {
  148. if (substr($this->domain, 0, 4) == 'www.') {
  149. $domain = substr($this->domain, 4);
  150. } else {
  151. $domain = 'www.'.$this->domain;
  152. }
  153. if (isset($this->routes[$domain])) {
  154. $this->domain = $domain;
  155. if (wa()->getEnv() == 'frontend' && !waRequest::param('no_domain_www_redirect')) {
  156. $url = 'http'.(waRequest::isHttps()? 's' : '').'://';
  157. $url .= $this->getDomainUrl($domain).'/'.wa()->getConfig()->getRequestUrl();
  158. wa()->getResponse()->redirect($url, 301);
  159. }
  160. }
  161. return $this->domain;
  162. }
  163. if ($return_alias && isset($this->aliases[$this->domain])) {
  164. $this->domain = $this->aliases[$this->domain];
  165. }
  166. return $this->domain;
  167. }
  168. protected function getDomainNoAlias()
  169. {
  170. $domain = waRequest::server('HTTP_HOST');
  171. if (!$domain) {
  172. return null;
  173. }
  174. $pos = strpos($domain, ':');
  175. if ($pos !== false) {
  176. $port = substr($domain, $pos + 1);
  177. if ($port == '80' || $port === '443') {
  178. $domain = substr($domain, 0, $pos);
  179. }
  180. }
  181. $u = trim($this->system->getRootUrl(), '/');
  182. if ($u) {
  183. $domain .= '/'.$u;
  184. }
  185. return $domain;
  186. }
  187. public function getRootUrl()
  188. {
  189. return $this->root_url;
  190. }
  191. public function dispatch()
  192. {
  193. $url = $this->system->getConfig()->getRequestUrl(true, true);
  194. $url = urldecode($url);
  195. $r = $this->dispatchRoutes($this->getRoutes(), $url);
  196. if (!$r || ($r['url'] == '*' && $url && strpos(substr($url, -5), '.') === false) && substr($url, -1) !== '/') {
  197. $r2 = $this->dispatchRoutes($this->getRoutes(), $url.'/');
  198. if ($r2 && (!$r || $r2['url'] != '*')) {
  199. $this->system->getResponse()->redirect($this->system->getRootUrl().$url.'/', 301);
  200. }
  201. }
  202. // if route found and app exists
  203. if ($r && isset($r['app']) && $r['app'] && $this->system->appExists($r['app'])) {
  204. $this->setRoute($r);
  205. // dispatch app routes
  206. $params = waRequest::param();
  207. $u = $r['url'];
  208. if (preg_match_all('/<([a-z_]+):?([^>]*)?>/ui', $u, $match, PREG_OFFSET_CAPTURE|PREG_SET_ORDER)) {
  209. $offset = 0;
  210. foreach ($match as $m) {
  211. $v = $m[1][0];
  212. $s = (isset($params[$v]) && $v != 'url') ? $params[$v] : '';
  213. $u = substr($u, 0, $m[0][1] + $offset).$s.substr($u, $m[0][1] + $offset + strlen($m[0][0]));
  214. $offset += strlen($s) - strlen($m[0][0]);
  215. }
  216. }
  217. $this->root_url = self::clearUrl($u);
  218. $url = isset($params['url']) ? $params['url'] : substr($url, strlen($this->root_url));
  219. $this->dispatchRoutes($this->getAppRoutes($r['app'], $r, true), $url);
  220. }
  221. return $r;
  222. }
  223. public function getRouteParam($name)
  224. {
  225. if ($this->route && isset($this->route[$name])) {
  226. return $this->route[$name];
  227. }
  228. return null;
  229. }
  230. public function getCurrentUrl()
  231. {
  232. $url = $this->system->getConfig()->getRequestUrl();
  233. $url = preg_replace("!\?.*$!", '', $url);
  234. $url = urldecode($url);
  235. return substr($url, strlen($this->root_url));
  236. }
  237. /**
  238. * Returns routes for pages
  239. * @param string $app_id APP_ID
  240. * @return array
  241. */
  242. protected function getPageRoutes($app_id, $route = array())
  243. {
  244. static $_page_routes;
  245. if ($_page_routes === null || !isset($_page_routes[$app_id])) {
  246. if ($cache = wa($app_id)->getCache()) {
  247. $cache_key = 'urls/'.self::getDomain(null, true). '/'. self::clearUrl($route['url']);
  248. $rows = $cache->get($cache_key, 'pages');
  249. }
  250. if (!$cache || $rows === null) {
  251. $class = $app_id . 'PageModel';
  252. /**
  253. * @var waPageModel $model
  254. */
  255. $model = new $class();
  256. $query = $model->select('id, full_url');
  257. $query->where("domain = ? AND route = ?", array(self::getDomain(null, true), $route['url']));
  258. if (!waRequest::get('preview')) {
  259. $query->where("status = 1");
  260. }
  261. $rows = $query->fetchAll();
  262. if ($cache) {
  263. $cache->set($cache_key, $rows, 3600, 'pages');
  264. }
  265. }
  266. $page_routes = array();
  267. foreach ($rows as $row) {
  268. $page_routes[] = array(
  269. 'url' => $row['full_url'],
  270. 'module' => 'frontend',
  271. 'action' => 'page',
  272. 'page_id' => $row['id']
  273. );
  274. }
  275. $_page_routes[$app_id] = $page_routes;
  276. }
  277. return $_page_routes[$app_id];
  278. }
  279. protected function getAppRoutes($app, $route = array(), $dispatch = false)
  280. {
  281. if (!$dispatch) {
  282. $cache_key = md5(serialize($route));
  283. $cache = new waRuntimeCache('approutes/'.$app.'/'.$cache_key, -1, 'webasyst');
  284. if ($cache->isCached()) {
  285. return $cache->get();
  286. }
  287. }
  288. $routes = waSystem::getInstance($app, null, $dispatch)->getConfig()->getRouting($route, $dispatch);
  289. $routes = $this->formatRoutes($routes, $app);
  290. if ($dispatch && wa($app)->getConfig()->getInfo('pages') && $app != 'site') {
  291. $page_routes = $this->getPageRoutes($app, $route);
  292. if ($page_routes) {
  293. $routes = array_merge($page_routes, $routes);
  294. }
  295. } else if (isset($cache)) {
  296. $cache->set($routes);
  297. }
  298. return $routes;
  299. }
  300. public function getRuleForUrl($routes, $url) {
  301. $result = null;
  302. foreach ($routes as $r) {
  303. if ($this->route && isset($this->route['module']) &&
  304. (!isset($r['module']) || $r['module'] != $this->route['module'])) {
  305. continue;
  306. }
  307. $pattern = str_replace(array(' ', '.', '('), array('\s', '\.', '(?:'), ifset($r, 'url', ''));
  308. $pattern = preg_replace('/(^|[^\.])\*/ui', '$1.*?', $pattern);
  309. if (preg_match_all('/<([a-z_]+):?([^>]*)?>/ui', $pattern, $match, PREG_OFFSET_CAPTURE|PREG_SET_ORDER)) {
  310. $offset = 0;
  311. foreach ($match as $m) {
  312. if ($m[2][0]) {
  313. $p = $m[2][0];
  314. } else {
  315. $p = '.*?';
  316. }
  317. $pattern = substr($pattern, 0, $offset + $m[0][1]).'('.$p.')'.substr($pattern, $offset + $m[0][1] + strlen($m[0][0]));
  318. $offset = $offset + strlen($p) + 2 - strlen($m[0][0]);
  319. }
  320. }
  321. if (preg_match('!^'.$pattern.'$!ui', $url, $match)) {
  322. $result = $r;
  323. break;
  324. }
  325. }
  326. return $result;
  327. }
  328. protected function dispatchRoutes($routes, $url)
  329. {
  330. $result = null;
  331. foreach ($routes as $r) {
  332. if (($this->route && isset($this->route['module']) &&
  333. (!isset($r['module']) || $r['module'] != $this->route['module']))
  334. || (isset($r['redirect']) && !empty($r['disabled']))
  335. ) {
  336. continue;
  337. }
  338. $vars = array();
  339. $pattern = str_replace(array(' ', '.', '('), array('\s', '\.', '(?:'), ifset($r, 'url', ''));
  340. $pattern = preg_replace('/(^|[^\.])\*/ui', '$1.*?', $pattern);
  341. if (preg_match_all('/<([a-z_]+):?([^>]*)?>/ui', $pattern, $match, PREG_OFFSET_CAPTURE|PREG_SET_ORDER)) {
  342. $offset = 0;
  343. foreach ($match as $m) {
  344. $vars[] = $m[1][0];
  345. if ($m[2][0]) {
  346. $p = $m[2][0];
  347. } else {
  348. $p = '.*?';
  349. }
  350. $pattern = substr($pattern, 0, $offset + $m[0][1]).'('.$p.')'.substr($pattern, $offset + $m[0][1] + strlen($m[0][0]));
  351. $offset = $offset + strlen($p) + 2 - strlen($m[0][0]);
  352. }
  353. }
  354. if (preg_match('!^'.$pattern.'$!ui', $url, $match)) {
  355. if (isset($r['redirect']) && empty($r['disabled'])) {
  356. $p = str_replace('.*?', '(.*?)', $pattern);
  357. if ($p != $pattern) {
  358. preg_match('!^'.$p.'$!ui', $url, $m);
  359. if (isset($m[1])) {
  360. $r['redirect'] = str_replace('*', $m[1], $r['redirect']);
  361. if (waRequest::server('QUERY_STRING')) {
  362. $r['redirect'] .= '?'.waRequest::server('QUERY_STRING');
  363. }
  364. }
  365. }
  366. $redirect_code = (!empty($r['code']) && $r['code'] == 302) ? 302 : 301;
  367. wa()->getResponse()->redirect($r['redirect'], $redirect_code);
  368. } elseif (isset($r['static_content'])) {
  369. $response = wa()->getResponse();
  370. switch (ifset($r['static_content_type'])){
  371. case 'text/plain':
  372. $response->addHeader('Content-Type', 'text/plain; charset=utf-8');
  373. break;
  374. case 'text/html':
  375. $response->addHeader('Content-Type', 'text/html; charset=utf-8');
  376. break;
  377. default:
  378. if ($type = waFiles::getMimeType($r['url'])) {
  379. $response->addHeader('Content-Type', $type);
  380. }
  381. break;
  382. }
  383. $response->sendHeaders();
  384. print $r['static_content'];
  385. exit;
  386. }
  387. if ($vars) {
  388. array_shift($match);
  389. foreach ($vars as $i => $v) {
  390. if (isset($match[$i]) && !waRequest::param($v)) {
  391. waRequest::setParam($v, $match[$i]);
  392. }
  393. }
  394. }
  395. foreach ($r as $k => $v) {
  396. if ($k !== 'url') {
  397. waRequest::setParam($k, $v);
  398. }
  399. }
  400. $result = $r;
  401. break;
  402. }
  403. }
  404. return $result;
  405. }
  406. /**
  407. * @param string $path
  408. * @param array $params
  409. * @param bool $absolute
  410. * @param string $domain_url
  411. * @param string $route_url
  412. * @return string
  413. */
  414. public function getUrl($path, $params = array(), $absolute = false, $domain_url = null, $route_url = null)
  415. {
  416. if (is_bool($params)) {
  417. $absolute = $params;
  418. $params = array();
  419. }
  420. $parts = explode('/', $path);
  421. $app = $parts[0];
  422. if (!$app) {
  423. $app = $this->system->getApp();
  424. }
  425. if (!$this->appExists($app)) {
  426. return null;
  427. }
  428. if (isset($parts[1])) {
  429. $params['module'] = $parts[1];
  430. }
  431. if (isset($parts[2])) {
  432. $params['action'] = $parts[2];
  433. }
  434. $routes = array();
  435. $current_domain = $this->getDomain();
  436. $is_set_route = $this->route && is_array($this->route);
  437. $is_current_route = true;
  438. $is_different_app = false;
  439. $is_different_domain = $is_set_route && $domain_url && $domain_url != $current_domain;
  440. $is_different_route_url = false;
  441. $is_different_module = false;
  442. if ($is_set_route) {
  443. foreach ($params as $k => $v) {
  444. if ($k != 'url' && isset($this->route[$k]) && $this->route[$k] != $v) {
  445. $is_current_route = false;
  446. break;
  447. }
  448. }
  449. $is_different_app = $this->route['app'] != $app;
  450. $is_different_route_url = $route_url && $this->route['url'] != $route_url;
  451. $is_different_module = isset($this->route['module']) && isset($params['module'])
  452. && $this->route['module'] != $params['module'];
  453. }
  454. $is_current_route = $is_current_route && !$is_different_app
  455. && !$is_different_domain && !$is_different_route_url && !$is_different_module;
  456. if (!$is_set_route || !$is_current_route) {
  457. if (isset($params['domain']) && !$domain_url) {
  458. $domain_url = $params['domain'];
  459. unset($params['domain']);
  460. }
  461. if ($domain_url) {
  462. $routes[$domain_url] = $this->getRoutes($domain_url);
  463. } else {
  464. $routes = $this->routes;
  465. }
  466. foreach ($routes as $domain => $domain_routes) {
  467. foreach ($domain_routes as $i => $route) {
  468. $is_different_app = !isset($route['app']) || $route['app'] != $app;
  469. $is_different_route_url = $domain_url && $route_url && $route['url'] != $route_url;
  470. $is_different_module = isset($params['module']) && isset($route['module'])
  471. && $route['module'] != $params['module'];
  472. if ($is_different_app || $is_different_route_url || $is_different_module) {
  473. unset($routes[$domain][$i]);
  474. }
  475. }
  476. if (!$routes[$domain]) {
  477. unset($routes[$domain]);
  478. }
  479. }
  480. } else {
  481. $routes[$current_domain] = array($this->route);
  482. }
  483. $max = -1;
  484. $result = null;
  485. foreach ($routes as $domain => $domain_routes) {
  486. foreach ($domain_routes as $route) {
  487. $route_score = $this->countParams($route, $params);
  488. if (isset($params['module']) && isset($route['module'])) {
  489. $route_score++;
  490. }
  491. if ($route_score > $max) {
  492. $max = $route_score;
  493. $result = array(
  494. 'domain' => $domain,
  495. 'route' => $route,
  496. 'params' => $params,
  497. 'app_route' => null,
  498. 'url_placeholders' => null,
  499. );
  500. }
  501. $app_routes = $this->getAppRoutes($route['app'], $route);
  502. foreach ($app_routes as $app_route) {
  503. $app_route_score = $route_score + $this->countParams($app_route, $params);
  504. if (empty($params['action']) && empty($app_route['action'])) {
  505. $app_route_score++;
  506. }
  507. $url = $app_route['url'];
  508. $url_placeholders = $this->getUrlPlaceholders($url);
  509. foreach ($url_placeholders as $url_placeholder) {
  510. $k = $url_placeholder['key'];
  511. $is_optional = $url_placeholder['is_optional'];
  512. if (isset($params[$k])) {
  513. $app_route_score++;
  514. } elseif (!$is_optional) {
  515. continue 2;
  516. }
  517. }
  518. $is_preferred_domain = !$current_domain || $domain == $current_domain;
  519. $is_overflow_max = $app_route_score > $max || ($app_route_score == $max && $is_preferred_domain);
  520. if ($is_overflow_max || !isset($result)) {
  521. $max = $app_route_score;
  522. $result = array(
  523. 'domain' => $domain,
  524. 'route' => $route,
  525. 'params' => $params,
  526. 'app_route' => $app_route,
  527. 'url_placeholders' => $url_placeholders,
  528. );
  529. }
  530. }
  531. }
  532. }
  533. $result_url = null;
  534. if (isset($result)) {
  535. if ($absolute && // When asked for an absolute URL
  536. $current_domain == $result['domain'] && // to current domain,
  537. $current_domain != $domain_url && // and did not specifically ask for original domain,
  538. $this->aliases // and there's possibility we're on a mirror (alias) domain
  539. ) {
  540. // if we are indeed on a mirror domain, then use full url to mirror instead of original domain.
  541. $alias_domain = $this->getDomainNoAlias();
  542. if (ifset($this->aliases, $alias_domain, null) == $current_domain) {
  543. $result['domain'] = $alias_domain;
  544. }
  545. }
  546. $result_url = self::getUrlByRoute($result['route'], $result['domain'], ($absolute || $current_domain != $result['domain']));
  547. $result_url = preg_replace('/<url.*?>/i', '', $result_url);
  548. if (isset($result['app_route'])) {
  549. $url = $result['app_route']['url'];
  550. $url_placeholders = $result['url_placeholders'];
  551. $params = $result['params'];
  552. $offset = 0;
  553. foreach ($url_placeholders as $url_placeholder) {
  554. $k = $url_placeholder['key'];
  555. $start = $url_placeholder['start'];
  556. $length = $url_placeholder['length'];
  557. if (isset($params[$k])) {
  558. $url = substr($url, 0, $start + $offset)
  559. . $params[$k]
  560. . substr($url, $start + $offset + $length);
  561. $offset += strlen($params[$k]) - $length;
  562. } else {
  563. $url = substr($url, 0, $start - 1)
  564. . substr($url, $start + $length + 3);
  565. }
  566. }
  567. $url = self::clearUrl($url);
  568. if (substr($result_url, -1) == '/' && substr($url, 0, 1) == '/') {
  569. $url = substr($url, 1);
  570. }
  571. $result_url = $result_url . $url;
  572. }
  573. }
  574. return $result_url;
  575. }
  576. /**
  577. * @since 1.14.13
  578. */
  579. protected function appExists($app_id)
  580. {
  581. // overriden in unit tests
  582. return wa()->appExists($app_id);
  583. }
  584. protected function getUrlPlaceholders($url) {
  585. if (!isset($this->url_placeholders[$url])) {
  586. if (preg_match_all(
  587. '/<([a-z_]+):?([^>]*)?>/ui',
  588. $url, $match, PREG_OFFSET_CAPTURE|PREG_SET_ORDER
  589. )) {
  590. $url_placeholders = array();
  591. foreach ($match as $m) {
  592. $k = $m[1][0];
  593. $start = $m[0][1];
  594. $length = strlen($m[0][0]);
  595. $is_optional = substr($url, $start - 1, 1) === '('
  596. && substr($url, $start + $length, 3) === '/)?';
  597. $url_placeholders[] = array(
  598. 'key' => $k,
  599. 'start' => $start,
  600. 'length' => $length,
  601. 'is_optional' => $is_optional,
  602. );
  603. }
  604. $this->url_placeholders[$url] = $url_placeholders;
  605. } else {
  606. $this->url_placeholders[$url] = array();
  607. }
  608. }
  609. return $this->url_placeholders[$url];
  610. }
  611. protected function countParams($r, $params)
  612. {
  613. $n = 0;
  614. foreach ($params as $key => $value) {
  615. if (isset($r[$key]) && $r[$key] == $value) {
  616. $n++;
  617. }
  618. }
  619. return $n;
  620. }
  621. /**
  622. * @static
  623. * @param array $route
  624. * @param string $domain
  625. * @return string
  626. */
  627. public static function getUrlByRoute($route, $domain = null, $absolute = true)
  628. {
  629. $result = self::clearUrl($route['url']);
  630. if ($domain) {
  631. $result = self::getDomainUrl($domain, $absolute).'/'.$result;
  632. if ($absolute) {
  633. if (!empty($route['ssl_all'])) {
  634. $https = true;
  635. } elseif (parse_url('http://'.$domain, PHP_URL_HOST) == waRequest::server('HTTP_HOST')) {
  636. $https = waRequest::isHttps();
  637. } else {
  638. $https = false;
  639. }
  640. $result = 'http'.($https ? 's' : '').'://'.$result;
  641. }
  642. }
  643. return $result;
  644. }
  645. public static function clearUrl($url)
  646. {
  647. return preg_replace('~(?<=/)\?|\.?\*$~i', '', $url);
  648. }
  649. public static function getDomainUrl($domain, $absolute = true)
  650. {
  651. $domain_parts = @parse_url('http://'.$domain);
  652. $result = isset($domain_parts['path']) ? $domain_parts['path'] : '';
  653. if (!waSystemConfig::systemOption('mod_rewrite')) {
  654. // without /index.php/
  655. $root_url_static = rtrim(wa()->getRootUrl(false, false), '/');
  656. // with /index.php/
  657. $root_url_script = rtrim(wa()->getRootUrl(false, true), '/');
  658. // Add /index.php/ to result in appropriate place
  659. if (substr($result, 0, strlen($root_url_static)) == $root_url_static) {
  660. $result = $root_url_script.substr($result, strlen($root_url_static));
  661. }
  662. }
  663. if ($absolute) {
  664. $host = $domain_parts['host'].(isset($domain_parts['port']) ? ':'.$domain_parts['port'] : '');
  665. return $host.$result;
  666. } else {
  667. return $result;
  668. }
  669. }
  670. public static function getDomainConfig($name=null, $domain=null)
  671. {
  672. static $domain_configs = array();
  673. if ($domain === null) {
  674. $domain = wa()->getRouting()->getDomain(null, true);
  675. }
  676. if (!$domain || false !== strpos($domain, '..')) {
  677. return $name === null ? array() : null;
  678. }
  679. if (!isset($domain_configs[$domain])) {
  680. $domain = waIdna::enc($domain);
  681. }
  682. if (!isset($domain_configs[$domain])) {
  683. $domain_configs[$domain] = array();
  684. $domain_config_path = wa()->getConfig()->getConfigPath('domains/' . $domain . '.php', true, 'site');
  685. if (file_exists($domain_config_path)) {
  686. $domain_configs[$domain] = include($domain_config_path);
  687. }
  688. }
  689. if ($name === null) {
  690. return $domain_configs[$domain];
  691. } else if (isset($domain_configs[$domain][$name])) {
  692. return $domain_configs[$domain][$name];
  693. } else {
  694. return null;
  695. }
  696. }
  697. }