SproutCMS

This is the code documentation for the SproutCMS project

source of /sprout/Helpers/SubsiteSelector.php

  1. <?php
  2. /*
  3.  * Copyright (C) 2017 Karmabunny Pty Ltd.
  4.  *
  5.  * This file is a part of SproutCMS.
  6.  *
  7.  * SproutCMS is free software: you can redistribute it and/or modify it under the terms
  8.  * of the GNU General Public License as published by the Free Software Foundation, either
  9.  * version 2 of the License, or (at your option) any later version.
  10.  *
  11.  * For more information, visit <http://getsproutcms.com>.
  12.  */
  13.  
  14. namespace Sprout\Helpers;
  15.  
  16. use Exception;
  17.  
  18. use karmabunny\pdb\Exceptions\QueryException;
  19.  
  20.  
  21. class SubsiteSelector
  22. {
  23. static public $subsite_id = 0;
  24. static public $content_id = 0;
  25. static public $subsite_code = '';
  26. static public $url_prefix = '';
  27. static public $mobile = false;
  28.  
  29.  
  30. /**
  31.   * Selects a single subsite by looking up the provided subsite code
  32.   * Subsite code is provided by the .htaccess file
  33.   **/
  34. static public function selectSubsite()
  35. {
  36. if (!empty(self::$subsite_code)) return;
  37.  
  38. try {
  39. $q = "SELECT id, content_id, code, mobile, cond_domain, cond_directory, require_admin, require_user
  40. FROM ~subsites
  41. WHERE active = 1
  42. ORDER BY id";
  43. $res = Pdb::query($q, [], 'arr');
  44. } catch (QueryException $ex) {
  45. self::$subsite_id = 1;
  46. self::$content_id = 1;
  47. self::$subsite_code = 'default';
  48. return;
  49. }
  50.  
  51. if (count($res) == 0) {
  52. if (!preg_match('!^(admin|admin_ajax|testing|dbtools)!', Router::$current_uri)) {
  53. throw new Exception('This website does not have any accessable subsites defined');
  54. }
  55. }
  56.  
  57. // Choose the best subsite for our situation
  58. $selected = null;
  59. $default = null;
  60. foreach ($res as $row) {
  61. if (!$row['cond_domain'] and !$row['cond_directory']) {
  62. if (!$default) $default = $row;
  63. continue;
  64. }
  65.  
  66. $cond_domains = array_filter(preg_split('/[\r\n]/', $row['cond_domain']));
  67.  
  68. // If the site is mobile and on a different domain, redirect
  69. if ($row['mobile'] and !in_array($_SERVER['HTTP_HOST'], $cond_domains)) {
  70. // Does the user want the mobile site?
  71. Session::instance();
  72. if (isset($_GET['mobile'])) {
  73. $_SESSION['mobile'] = (int)$_GET['mobile'];
  74. } else if (!isset($_SESSION['mobile'])) {
  75. $_SESSION['mobile'] = 1;
  76. }
  77.  
  78. // If mobile is desired, do the redirect
  79. if ($_SESSION['mobile'] == 1) {
  80. $ua_info = UserAgent::getInfo();
  81. if ($ua_info['device_category'] == 'Mobile') {
  82. $_SERVER['HTTP_HOST'] = $cond_domains[0];
  83. Url::redirect(Url::base(false, 'http') . Url::current(true));
  84. }
  85. }
  86. }
  87.  
  88. // Check domain matches
  89. if (count($cond_domains)) {
  90. if (!in_array($_SERVER['HTTP_HOST'], $cond_domains)) continue;
  91. }
  92.  
  93. // Check directory matches
  94. if ($row['cond_directory']) {
  95. $pos = strpos(Router::$current_uri, $row['cond_directory']);
  96. if (! ($pos === 0)) continue;
  97. }
  98.  
  99. // If admin access is required to view the subsite
  100. if ($row['require_admin']) {
  101. if (! AdminAuth::isLoggedIn()) continue;
  102. }
  103.  
  104. // If user access is required to view the subsite
  105. if ($row['require_user']) {
  106. if (! Register::hasFeature('users')) continue;
  107. if (! UserAuth::isLoggedIn()) continue;
  108. }
  109.  
  110. $selected = $row;
  111. break;
  112. }
  113.  
  114. if (! $selected) {
  115. $selected = $default;
  116.  
  117. // Check admin or user auth requirements for default subsite
  118. if (!AdminAuth::isLoggedIn() and PHP_SAPI !== 'cli') {
  119. if ($default['require_admin'] and !preg_match('!^(admin|admin_ajax|file)/!', Router::$current_uri)) {
  120. AdminAuth::checkLogin();
  121. }
  122.  
  123. if ($default['require_user'] and Register::hasFeature('users') and !preg_match('!^user/!', Router::$current_uri)) {
  124. UserAuth::checkLogin();
  125. }
  126. }
  127. }
  128.  
  129. if ($selected === null) {
  130. if (!preg_match('!^(admin|admin_ajax|testing|dbtools)!', Router::$current_uri)) {
  131. throw new Exception('This website does not have any accessable subsites defined');
  132. }
  133. }
  134.  
  135. // For directory subsites, we need to nuke the leading directory part
  136. $directory = trim($selected['cond_directory'], '/');
  137. if ($directory) {
  138. Router::$current_uri = trim(preg_replace('!^' . preg_quote($directory) . '!', '', Router::$current_uri), '/');
  139. $directory .= '/';
  140. }
  141.  
  142. self::$subsite_id = $selected['id'];
  143. self::$content_id = $selected['content_id'] ? $selected['content_id'] : $selected['id'];
  144. self::$subsite_code = $selected['code'];
  145. self::$url_prefix = $directory;
  146. self::$mobile = $selected['mobile'];
  147. }
  148. }
  149.