PageRenderTime 59ms CodeModel.GetById 13ms RepoModel.GetById 1ms app.codeStats 0ms

/lib/Kurogo.php

http://github.com/modolabs/Kurogo-Mobile-Web
PHP | 1724 lines | 1332 code | 293 blank | 99 comment | 209 complexity | ccbf8eeb4207422908ca25ed6574d2de MD5 | raw file
Possible License(s): LGPL-3.0, LGPL-2.1

Large files files are truncated, but you can click here to view the full file

  1. <?php
  2. /*
  3. * Copyright © 2010 - 2013 Modo Labs Inc. All rights reserved.
  4. *
  5. * The license governing the contents of this file is located in the LICENSE
  6. * file located at the root directory of this distribution. If the LICENSE file
  7. * is missing, please contact sales@modolabs.com.
  8. *
  9. */
  10. //
  11. // Constants which cannot be set by config file
  12. //
  13. define('KUROGO_VERSION', '1.8.6');
  14. define('ROOT_DIR', realpath(dirname(__FILE__).'/..'));
  15. define('ROOT_BASE_DIR', realpath(dirname(__FILE__).'/../..'));
  16. define('WEBROOT_DIR', ROOT_DIR . DIRECTORY_SEPARATOR . 'www');
  17. define('LIB_DIR', ROOT_DIR . DIRECTORY_SEPARATOR . 'lib');
  18. define('APP_DIR', ROOT_DIR . DIRECTORY_SEPARATOR . 'app');
  19. define('MODULES_DIR', APP_DIR . DIRECTORY_SEPARATOR . 'modules');
  20. define('SCRIPTS_DIR', ROOT_DIR . DIRECTORY_SEPARATOR . 'scripts');
  21. define('MIN_FILE_PREFIX', 'file-');
  22. define('API_URL_PREFIX', 'rest');
  23. define('KUROGO_REQUIRED_VERSION', '5.3.0');
  24. if (version_compare(PHP_VERSION, KUROGO_REQUIRED_VERSION, '<')) {
  25. die('Kurogo requires at least PHP version ' . KUROGO_REQUIRED_VERSION . '. You have version ' . PHP_VERSION);
  26. }
  27. //
  28. // And a double quote define for ini files (php 5.1 can't escape them)
  29. //
  30. define('_QQ_', '"');
  31. /* this is a singleton class */
  32. class Kurogo
  33. {
  34. private static $_instance = NULL;
  35. private function __clone() {}
  36. protected $charset='UTF-8';
  37. protected $configClass = 'ConfigFile';
  38. protected $startTime;
  39. protected $libDirs = array();
  40. protected $site;
  41. protected $baseConfigStore;
  42. protected $siteConfigStore;
  43. protected $configModes = array();
  44. protected $themeConfig;
  45. protected $deviceClassifier;
  46. protected $session;
  47. protected $logger;
  48. protected $timezone;
  49. protected $locale;
  50. protected $languages=array();
  51. protected $args=array();
  52. protected $cookies=array();
  53. protected $cacher;
  54. protected $module;
  55. protected $moduleID;
  56. protected $configModule;
  57. protected $request;
  58. protected $serverHost;
  59. protected $multiSite = false;
  60. protected $error_reporting = array();
  61. protected $contexts;
  62. const REDIRECT_PERMANENT = 301;
  63. const REDIRECT_TEMPORARY = 302;
  64. const REDIRECT_SEE_OTHER = 303;
  65. private function __construct() {
  66. $this->startTime = microtime(true);
  67. }
  68. public static function KurogoUserAgent() {
  69. return "Kurogo Server v" . KUROGO_VERSION;
  70. }
  71. protected function setConfigMode($configMode) {
  72. if ($configMode && !in_array($configMode, $this->configModes)) {
  73. Kurogo::log(LOG_DEBUG,"Adding config mode $configMode", 'config');
  74. $this->configModes[] = $configMode;
  75. }
  76. }
  77. public static function getConfigModes() {
  78. return self::sharedInstance()->configModes;
  79. }
  80. public function setCurrentModuleID($moduleID) {
  81. $this->moduleID = $moduleID;
  82. }
  83. public function setCurrentConfigModule($configModule) {
  84. $this->configModule = $configModule;
  85. }
  86. public function setCurrentModule(Module $module) {
  87. $this->module = $module;
  88. $this->moduleID = $module->getID();
  89. $this->configModule = $module->getConfigModule();
  90. }
  91. public function setRequest($id, $page, $args) {
  92. $this->request = array(
  93. 'id'=>$id,
  94. 'page'=>$page,
  95. 'args'=>$args
  96. );
  97. //moduleID is used by the autoloader
  98. $this->moduleID = $id;
  99. }
  100. public function getCurrentModule() {
  101. return $this->module;
  102. }
  103. public function getCurrentModuleID() {
  104. return $this->moduleID;
  105. }
  106. public static function getArrayForRequest() {
  107. $Kurogo = Kurogo::sharedInstance();
  108. return $Kurogo->request;
  109. }
  110. public static function getElapsed() {
  111. $Kurogo = self::sharedInstance();
  112. return microtime(true) - $Kurogo->startTime;
  113. }
  114. public static function getSession() {
  115. $Kurogo = self::sharedInstance();
  116. return $Kurogo->session();
  117. }
  118. public function session() {
  119. $this->addPackage('Session');
  120. if (!$this->session) {
  121. $args = Kurogo::getSiteSection('authentication');
  122. //default session class
  123. $controllerClass = 'SessionFiles';
  124. //maintain previous config compatibility
  125. if (isset($args['AUTHENTICATION_USE_SESSION_DB']) && $args['AUTHENTICATION_USE_SESSION_DB']) {
  126. $controllerClass = 'SessionDB';
  127. }
  128. if (isset($args['AUTHENTICATION_SESSION_CLASS'])) {
  129. $controllerClass = $args['AUTHENTICATION_SESSION_CLASS'];
  130. }
  131. $this->session = Session::factory($controllerClass, $args);
  132. }
  133. return $this->session;
  134. }
  135. public static function sharedInstance() {
  136. if (!isset(self::$_instance)) {
  137. $c = __CLASS__;
  138. self::$_instance = new $c;
  139. }
  140. return self::$_instance;
  141. }
  142. public static function tempDirectory() {
  143. return Kurogo::getOptionalSiteVar('TMP_DIR', sys_get_temp_dir());
  144. }
  145. public static function tempFile($prefix='kgo') {
  146. $tempDir = self::tempDirectory();
  147. if (!is_writable($tempDir)) {
  148. throw new KurogoConfigurationException("Temporary directory $tempDir not available");
  149. }
  150. $umask = umask(0177);
  151. $tempFile = tempnam($tempDir, $prefix);
  152. umask($umask);
  153. return $tempFile;
  154. }
  155. public static function moduleLinkForItem($moduleID, $object, $options=null) {
  156. $args = self::sharedInstance()->getArgs();
  157. $module = WebModule::factory($moduleID, null, $args);
  158. return $module->linkForItem($object, $options);
  159. }
  160. public static function moduleLinkForValue($moduleID, $value, Module $callingModule, $otherValue=null) {
  161. $args = self::sharedInstance()->getArgs();
  162. $module = WebModule::factory($moduleID, null, $args);
  163. return $module->linkForValue($value, $callingModule, $otherValue);
  164. }
  165. public static function searchItems($moduleID, $searchTerms, $limit=null, $options=null) {
  166. $args = self::sharedInstance()->getArgs();
  167. $module = WebModule::factory($moduleID, null, $args);
  168. return $module->searchItems($searchTerms, $limit, $options);
  169. }
  170. public static function includePackage($packageName, $subpackageName=null) {
  171. $Kurogo = self::sharedInstance();
  172. return $Kurogo->addPackage($packageName, $subpackageName);
  173. }
  174. public function addPackage($packageName, $subpackageName=null) {
  175. // allow Package/Subpackage string
  176. if (preg_match("#([a-zA-Z0-9]+)/([a-zA-Z0-9]+)#", $packageName, $bits)) {
  177. $packageName = $bits[1];
  178. $subpackageName = $bits[2];
  179. }
  180. if (!preg_match("/^[a-zA-Z0-9]+$/", $packageName)) {
  181. throw new KurogoConfigurationException("Invalid Package name $packageName");
  182. }
  183. if ($subpackageName !== null) {
  184. if (!preg_match("/^[a-zA-Z0-9]+$/", $subpackageName)) {
  185. throw new KurogoConfigurationException("Invalid Subpackage name $packageName");
  186. }
  187. $packageName .= DIRECTORY_SEPARATOR.$subpackageName;
  188. }
  189. $found = false;
  190. $dirs = array(LIB_DIR . "/$packageName");
  191. if (defined('SHARED_LIB_DIR')) {
  192. $dirs[] = SHARED_LIB_DIR . "/$packageName";
  193. }
  194. if (defined('SITE_LIB_DIR')) {
  195. $dirs[] = SITE_LIB_DIR . "/$packageName";
  196. }
  197. foreach ($dirs as $dir) {
  198. if (is_dir($dir)) {
  199. self::log(LOG_INFO, "Adding package $packageName", "autoLoader");
  200. $found = true;
  201. if ($this->addLibDir($dir)) {
  202. //load Package.php if the package hasn't already been loaded
  203. if (is_file("$dir.php")) {
  204. include_once("$dir.php");
  205. }
  206. }
  207. }
  208. }
  209. if (!$found) {
  210. throw new KurogoConfigurationException("Unable to load package $packageName");
  211. }
  212. }
  213. public static function includeModulePackage($packageName) {
  214. $Kurogo = self::sharedInstance();
  215. return $Kurogo->addModulePackage($packageName);
  216. }
  217. public function addModulePackage($packageName) {
  218. if (!$this->moduleID) {
  219. throw new KurogoException("Cannot call addModulePackage before a module is loaded");
  220. }
  221. if (!preg_match("/^[a-zA-Z0-9]+$/", $packageName)) {
  222. throw new KurogoException("Invalid Package name $packageName");
  223. }
  224. $dirs = array(
  225. implode('/', array(MODULES_DIR, $this->moduleID, 'lib', $packageName)),
  226. implode('/', array(SITE_MODULES_DIR, $this->moduleID, 'lib', $packageName))
  227. );
  228. $found = false;
  229. foreach ($dirs as $dir) {
  230. if (is_dir($dir)) {
  231. self::log(LOG_INFO, "Adding module package $this->moduleID/$packageName", "autoLoader");
  232. $found = true;
  233. if ($this->addLibDir($dir)) {
  234. //load Package.php if the package hasn't already been loaded
  235. if (is_file("$dir.php")) {
  236. include_once("$dir.php");
  237. }
  238. }
  239. }
  240. }
  241. if (!$found) {
  242. throw new KurogoConfigurationException("Unable to load package $packageName for module $this->moduleID");
  243. }
  244. }
  245. protected function getLibDirs() {
  246. return $this->libDirs;
  247. }
  248. public function addLibDir($dir) {
  249. if (!in_array($dir, $this->libDirs) && is_dir($dir)) {
  250. self::log(LOG_INFO, "Adding lib dir $dir", "autoLoader");
  251. $this->libDirs[] = $dir;
  252. return true;
  253. }
  254. //it's already there
  255. return false;
  256. }
  257. public static function addModuleLib($id) {
  258. if (defined('MODULES_DIR')) {
  259. $dir = implode('/', array(MODULES_DIR, $id, 'lib'));
  260. self::sharedInstance()->addLibDir($dir);
  261. }
  262. if (defined('SHARED_MODULES_DIR')) {
  263. $dir = implode('/', array(SHARED_MODULES_DIR, $id, 'lib'));
  264. self::sharedInstance()->addLibDir($dir);
  265. }
  266. if (defined('SITE_MODULES_DIR')) {
  267. $dir = implode('/', array(SITE_MODULES_DIR, $id, 'lib'));
  268. self::sharedInstance()->addLibDir($dir);
  269. }
  270. }
  271. /**
  272. * This function defines a autoloader that is run when a class needs to be instantiated but the corresponding
  273. * file has not been loaded. Files MUST be named with the same name as its class
  274. * currently it will search:
  275. * 1. If the className has Module in it, it will search the MODULES_DIR
  276. * 2. The SITE_LIB_DIR (keep in mind that some files may manually include the LIB_DIR class)
  277. * 3. The SHARED_LIB_DIR (keep in mind that some files may manually include the LIB_DIR class)
  278. * 4. The LIB_DIR
  279. *
  280. */
  281. public function siteLibAutoloader($className) {
  282. if ($classPath = Kurogo::getCache('autoload-' . $className)) {
  283. include($classPath);
  284. return ;
  285. }
  286. $paths = $this->getLibDirs();
  287. // If the className has Module in it then use the modules dir
  288. if (defined('MODULES_DIR') && preg_match("/(.+)(Web|API|Shell)Module$/", $className, $bits)) {
  289. $paths[] = MODULES_DIR . '/' . strtolower($bits[1]);
  290. }
  291. // use the shared lib dir if it's been defined
  292. if (defined('SHARED_LIB_DIR')) {
  293. $paths[] = SHARED_LIB_DIR;
  294. }
  295. // use the site lib dir if it's been defined
  296. if (defined('SITE_LIB_DIR')) {
  297. $paths[] = SITE_LIB_DIR;
  298. }
  299. $paths[] = LIB_DIR;
  300. self::log(LOG_DEBUG, "Autoloader loading $className", "autoLoader");
  301. foreach ($paths as $path) {
  302. $file = "$path/$className.php";
  303. // self::log(LOG_DEBUG, "Autoloader looking for $file for $className", "autoLoader");
  304. if (file_exists($file)) {
  305. self::log(LOG_INFO, "Autoloader found $file for $className", "autoLoader");
  306. Kurogo::setCache('autoload-' . $className, $file);
  307. include($file);
  308. return;
  309. }
  310. }
  311. return;
  312. }
  313. public static function isValidSiteName($name) {
  314. return preg_match("/^[a-z][a-z0-9_-]*$/i", $name);
  315. }
  316. public static function siteTimezone() {
  317. return Kurogo::sharedInstance()->getTimezone();
  318. }
  319. public function getTimezone() {
  320. return $this->timezone;
  321. }
  322. public static function getHost() {
  323. return self::sharedInstance()->_getHost();
  324. }
  325. public function _getHost() {
  326. return $this->site->getHost();
  327. }
  328. public function getSite() {
  329. return $this->site;
  330. }
  331. public static function getSiteConfig($area, $opts=0) {
  332. return self::sharedInstance()->getConfig($area, 'site', $opts);
  333. }
  334. public function saveConfig(Config $config) {
  335. return $this->siteConfigStore->saveConfig($config);
  336. }
  337. public function getConfig($area, $type, $opts=0) {
  338. $module = null;
  339. if ($type instanceOf Module) {
  340. $module = $type;
  341. $type = $module->getConfigModule();
  342. }
  343. $key = $type . '-' . $area;
  344. if (isset($this->configs[$key])) {
  345. return $this->configs[$key];
  346. }
  347. if ($config = $this->siteConfigStore->loadConfig($area, $type, $opts)) {
  348. $this->configs[$key] = $config;
  349. }
  350. return $config;
  351. }
  352. public function getConfigStore() {
  353. return $this->siteConfigStore;
  354. }
  355. public static function getModuleConfig($area, $configModule, $opts=0) {
  356. return self::sharedInstance()->getConfig($area, $configModule, $opts);
  357. }
  358. public function getDeviceClassifier() {
  359. if (!$this->deviceClassifier) {
  360. $this->deviceClassifier = new DeviceClassifier();
  361. }
  362. return $this->deviceClassifier;
  363. }
  364. public static function deviceClassifier() {
  365. return Kurogo::sharedInstance()->getDeviceClassifier();
  366. }
  367. public static function isWindows() {
  368. return strtoupper(substr(PHP_OS, 0, 3)) === 'WIN';
  369. }
  370. public static function isLocalhost() {
  371. return isset($_SERVER['REMOTE_ADDR']) && in_array($_SERVER['REMOTE_ADDR'], array('127.0.0.1', '::1'));
  372. }
  373. private static function checkIP($ip) {
  374. if (!empty($ip) && ip2long($ip)!=-1 && ip2long($ip)!=false) {
  375. $private_ips = array (
  376. array('0.0.0.0','2.255.255.255'),
  377. array('10.0.0.0','10.255.255.255'),
  378. array('127.0.0.0','127.255.255.255'),
  379. array('169.254.0.0','169.254.255.255'),
  380. array('172.16.0.0','172.31.255.255'),
  381. array('192.0.2.0','192.0.2.255'),
  382. array('192.168.0.0','192.168.255.255'),
  383. array('255.255.255.0','255.255.255.255')
  384. );
  385. foreach ($private_ips as $r) {
  386. $min = ip2long($r[0]);
  387. $max = ip2long($r[1]);
  388. if ((ip2long($ip) >= $min) && (ip2long($ip) <= $max)) return false;
  389. }
  390. return true;
  391. } else {
  392. return false;
  393. }
  394. }
  395. public static function determineIP() {
  396. if (isset($_SERVER['HTTP_CLIENT_IP']) && self::checkIP($_SERVER["HTTP_CLIENT_IP"])) {
  397. return $_SERVER["HTTP_CLIENT_IP"];
  398. }
  399. if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
  400. foreach (explode(",",$_SERVER["HTTP_X_FORWARDED_FOR"]) as $ip) {
  401. if (self::checkIP(trim($ip))) {
  402. return $ip;
  403. }
  404. }
  405. }
  406. if (isset($_SERVER['HTTP_X_FORWARDED']) && self::checkIP($_SERVER["HTTP_X_FORWARDED"])) {
  407. return $_SERVER["HTTP_X_FORWARDED"];
  408. } elseif (isset($_SERVER['HTTP_X_CLUSTER_CLIENT_IP']) && self::checkIP($_SERVER["HTTP_X_CLUSTER_CLIENT_IP"])) {
  409. return $_SERVER["HTTP_X_CLUSTER_CLIENT_IP"];
  410. } elseif (isset($_SERVER['HTTP_FORWARDED_FOR']) && self::checkIP($_SERVER["HTTP_FORWARDED_FOR"])) {
  411. return $_SERVER["HTTP_FORWARDED_FOR"];
  412. } elseif (isset($_SERVER['HTTP_FORWARDED']) && self::checkIP($_SERVER["HTTP_FORWARDED"])) {
  413. return $_SERVER["HTTP_FORWARDED"];
  414. } elseif (isset($_SERVER['REMOTE_ADDR'])) {
  415. return $_SERVER["REMOTE_ADDR"];
  416. }
  417. return false;
  418. }
  419. public static function file_upload_error_message($error_code) {
  420. switch ($error_code) {
  421. case UPLOAD_ERR_OK:
  422. return self::getLocalizedString('UPLOAD_ERR_OK');
  423. case UPLOAD_ERR_INI_SIZE:
  424. return self::getLocalizedString('UPLOAD_ERR_INI_SIZE', ini_get('upload_max_filesize'));
  425. case UPLOAD_ERR_FORM_SIZE:
  426. return self::getLocalizedString('UPLOAD_ERR_FORM_SIZE');
  427. case UPLOAD_ERR_PARTIAL:
  428. return self::getLocalizedString('UPLOAD_ERR_PARTIAL');
  429. case UPLOAD_ERR_NO_FILE:
  430. return self::getLocalizedString('UPLOAD_ERR_NO_FILE');
  431. case UPLOAD_ERR_NO_TMP_DIR:
  432. return self::getLocalizedString('UPLOAD_ERR_NO_TMP_DIR');
  433. case UPLOAD_ERR_CANT_WRITE:
  434. return self::getLocalizedString('UPLOAD_ERR_CANT_WRITE');
  435. case UPLOAD_ERR_EXTENSION:
  436. return self::getLocalizedString('UPLOAD_ERR_EXTENSION');
  437. default:
  438. return self::getLocalizedString('UPLOAD_ERR_UNKNOWN');
  439. }
  440. }
  441. public static function getAvailableLocales() {
  442. static $locales=array();
  443. if ($locales) {
  444. return $locales;
  445. }
  446. if (file_exists('/usr/bin/locale')) {
  447. exec('/usr/bin/locale -a', $locales, $retval);
  448. if ($retval!==0) {
  449. throw new KurogoException("Error retrieving locale values");
  450. }
  451. } else {
  452. throw new KurogoException("Unable to find list of locales on this platform");
  453. }
  454. return $locales;
  455. }
  456. public function getLocale() {
  457. return $this->locale;
  458. }
  459. public function getSystemLocale() {
  460. return setLocale(LC_ALL,"");
  461. }
  462. public function setArgs(array $args) {
  463. $this->args = $args;
  464. }
  465. public function getArgs() {
  466. return $this->args;
  467. }
  468. public function setLocale($locale) {
  469. if ($this->isWindows()) {
  470. throw new KurogoConfigurationException("Setting locale in Windows is not supported at this time");
  471. }
  472. // this is platform dependent.
  473. if (!$return = setLocale(LC_TIME, $locale)) {
  474. throw new KurogoConfigurationException("Unknown locale setting $locale");
  475. }
  476. $this->locale = $return;
  477. return $this->locale;
  478. }
  479. private function logger() {
  480. if (!$this->logger && $this->timezone && defined('LOG_DIR')) {
  481. require_once(LIB_DIR . '/KurogoLog.php');
  482. $this->logger = new KurogoLog();
  483. $logFilename = $this->getOptionalSiteVar('KUROGO_LOG_FILENAME', "kurogo.log");
  484. $logFile = LOG_DIR . DIRECTORY_SEPARATOR . $logFilename;
  485. $this->logger->setLogFile($logFile);
  486. $this->logger->setDefaultLogLevel($this->getOptionalSiteVar('DEFAULT_LOGGING_LEVEL', LOG_WARNING));
  487. if (($loggingLevels = $this->getOptionalSiteVar('LOGGING_LEVEL')) && is_array($loggingLevels)) {
  488. foreach ($loggingLevels as $area=>$level) {
  489. $this->logger->setLogLevel($area, $level);
  490. }
  491. }
  492. }
  493. return $this->logger;
  494. }
  495. public function cacher() {
  496. return $this->cacher;
  497. }
  498. public static function getCache($key) {
  499. if (!defined('SITE_NAME')) {
  500. return false;
  501. }
  502. $key = SITE_NAME . '-' . $key;
  503. if ($cacher = Kurogo::sharedInstance()->cacher()) {
  504. return $cacher->get($key);
  505. }
  506. // in the early stages the cacher is not available.
  507. // Kurogo::log(LOG_DEBUG, "Cacher not available for $key", 'cache');
  508. return false;
  509. }
  510. public static function setCache($key, $value, $ttl = null) {
  511. if (!defined('SITE_NAME')) {
  512. return false;
  513. }
  514. $key = SITES_KEY .'-' . SITE_NAME . '-' . $key;
  515. if ($cacher = Kurogo::sharedInstance()->cacher()) {
  516. $logValue = is_scalar($value) ? $value : gettype($value);
  517. Kurogo::log(LOG_DEBUG, "Setting $key to $logValue", 'cache');
  518. return $cacher->set($key, $value, $ttl);
  519. }
  520. return false;
  521. }
  522. public static function deleteCache($key) {
  523. if (!defined('SITE_NAME')) {
  524. return false;
  525. }
  526. $key = SITE_NAME . '-' . $key;
  527. if ($cacher = Kurogo::sharedInstance()->cacher()) {
  528. return $cacher->delete($key);
  529. }
  530. return false;
  531. }
  532. public static function clearCache() {
  533. if ($cacher = Kurogo::sharedInstance()->cacher()) {
  534. return $cacher->clear();
  535. }
  536. return false;
  537. }
  538. public function setDefaultLogLevel($level) {
  539. $logger = $this->logger();
  540. $logger->setDefaultLogLevel($level);
  541. }
  542. public function setLogLevel($area, $level) {
  543. $logger = $this->logger();
  544. $logger->setLogLevel($area, $level);
  545. }
  546. public static function log($priority, $message, $area, $backtrace=null) {
  547. static $deferredLogs = array();
  548. $logger = Kurogo::sharedInstance()->logger();
  549. if (!$logger) {
  550. if ($priority <= LOG_WARNING) {
  551. // we need to log early messages so they go SOMEWHERE
  552. error_log($message);
  553. }
  554. //this is a really early log before we have setup the config environment
  555. $args = func_get_args();
  556. $args[] = debug_backtrace();
  557. $deferredLogs[] = $args;
  558. return;
  559. }
  560. // replay the deferred logs.
  561. if ($deferredLogs) {
  562. foreach ($deferredLogs as $args) {
  563. $logger->log($args[0], $args[1], $args[2], $args[3]);
  564. }
  565. $deferredLogs = array();
  566. }
  567. return $logger->log($priority, $message, $area, $backtrace);
  568. }
  569. public static function isRequestSecure() {
  570. if (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') {
  571. return true;
  572. }
  573. if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https') {
  574. return true;
  575. }
  576. return false;
  577. }
  578. public function initialize(&$path=null) {
  579. includePackage('Cache');
  580. includePackage('Config');
  581. require(LIB_DIR.'/compat.php');
  582. require(LIB_DIR.'/exceptions.php');
  583. // add autoloader
  584. spl_autoload_register(array($this, "siteLibAutoloader"));
  585. //
  586. // Set up host define for server name and port
  587. //
  588. $host = self::arrayVal($_SERVER, 'SERVER_NAME', null);
  589. // SERVER_NAME never contains the port, while HTTP_HOST may (but we're not using HTTP_HOST for security reasons)
  590. if (isset($_SERVER['SERVER_PORT']) && $_SERVER['SERVER_PORT'] !== '80') {
  591. $host .= ":{$_SERVER['SERVER_PORT']}";
  592. }
  593. // It's possible (under apache at least) for SERVER_NAME to contain a comma separated list.
  594. if(strpos($host, ',') !== false)
  595. {
  596. self::log(LOG_DEBUG, "Got multiple hostnames in SERVER_NAME: $host", 'kurogo');
  597. $host_explode = explode(',', $host);
  598. // Only sane choice is to use the first one.
  599. $host = $host_explode[0];
  600. }
  601. define('SERVER_HOST', $host);
  602. self::log(LOG_DEBUG, "Setting server host to $host", "kurogo");
  603. define('IS_SECURE', self::isRequestSecure());
  604. define('HTTP_PROTOCOL', IS_SECURE ? 'https' : 'http');
  605. $this->baseConfigStore = new ConfigFileStore();
  606. // Load main configuration file.
  607. $kurogoConfig = $this->loadKurogoConfig();
  608. // get CONFIG_MODE from environment if available.
  609. $configMode = Kurogo::arrayVal($_SERVER, 'CONFIG_MODE', null);
  610. if ($configMode = $kurogoConfig->getOptionalVar('CONFIG_MODE', $configMode, 'kurogo')) {
  611. $this->setConfigMode($configMode);
  612. }
  613. if ($cacheClass = $kurogoConfig->getOptionalVar('CACHE_CLASS','', 'cache')) {
  614. $this->cacher = KurogoMemoryCache::factory($cacheClass, $kurogoConfig->getOptionalSection('cache'));
  615. }
  616. // get SITES_DIR from environment if available.
  617. $_sitesDir = Kurogo::arrayVal($_SERVER, 'SITES_DIR', ROOT_BASE_DIR . DIRECTORY_SEPARATOR . 'sites');
  618. $_sitesDir = $kurogoConfig->getOptionalVar('SITES_DIR', $_sitesDir , 'kurogo');
  619. if (!$sitesDir = realpath($_sitesDir)) {
  620. throw new KurogoConfigurationException("SITES_DIR $_sitesDir does not exist");
  621. }
  622. define('SITES_DIR', $sitesDir);
  623. define('SITES_KEY', md5(SITES_DIR));
  624. //
  625. // Initialize Site
  626. //
  627. $this->initSite($path);
  628. $this->setCharset($this->getOptionalSiteVar('DEFAULT_CHARSET', 'UTF-8'));
  629. ini_set('default_charset', $this->charset());
  630. ini_set('display_errors', $this->getSiteVar('DISPLAY_ERRORS'));
  631. if (!ini_get('error_log')) {
  632. ini_set('error_log', LOG_DIR . DIRECTORY_SEPARATOR . 'php_error.log');
  633. }
  634. define('KUROGO_IS_API', preg_match("#^" .API_URL_PREFIX . "/#", $path));
  635. //
  636. // Install exception handlers
  637. //
  638. if ($this->getSiteVar('PRODUCTION_ERROR_HANDLER_ENABLED')) {
  639. set_exception_handler("exceptionHandlerForProduction");
  640. } else {
  641. set_exception_handler("exceptionHandlerForDevelopment");
  642. }
  643. //get timezone from config and set
  644. $timezone = $this->getSiteVar('LOCAL_TIMEZONE');
  645. date_default_timezone_set($timezone);
  646. $this->timezone = new DateTimeZone($timezone);
  647. self::log(LOG_DEBUG, "Setting timezone to $timezone", "kurogo");
  648. if ($locale = $this->getOptionalSiteVar('LOCALE')) {
  649. $this->setLocale($locale);
  650. } else {
  651. $this->locale = $this->getSystemLocale();
  652. }
  653. if ($languages = $this->getOptionalSiteVar('LANGUAGES')) {
  654. $this->setLanguages($languages);
  655. } else {
  656. $this->setLanguages(array('en_US'));
  657. }
  658. //
  659. // everything after this point only applies to http requests
  660. //
  661. if (PHP_SAPI == 'cli') {
  662. define('FULL_URL_BASE','');
  663. return;
  664. }
  665. define('FULL_URL_BASE', 'http'.(IS_SECURE ? 's' : '').'://'.$this->_getHost().URL_BASE);
  666. define('COOKIE_PATH', URL_BASE);
  667. // make sure host is all lower case
  668. if ($this->_getHost() != strtolower($this->_getHost())) {
  669. $url = 'http'.(IS_SECURE ? 's' : '').'://' . strtolower($this->_getHost()) . $path;
  670. self::log(LOG_INFO, "Redirecting to lowercase url $url", 'kurogo');
  671. Kurogo::redirectToURL($url, Kurogo::REDIRECT_PERMANENT);
  672. }
  673. //
  674. // Initialize global device classifier
  675. //
  676. $device = null;
  677. $deviceCacheTimeout = self::getSiteVar('DEVICE_DETECTION_COOKIE_LIFESPAN', 'cookies');
  678. $urlPrefix = URL_BASE;
  679. $urlDeviceDebugPrefix = '/';
  680. $override = null;
  681. if (isset($_GET['resetdevice'])) {
  682. DeviceClassifier::clearDeviceCookie();
  683. }
  684. if (isset($_GET['setdevice'])) {
  685. $device = $_GET['setdevice'];
  686. $override = 1;
  687. $deviceCacheTimeout = 0;
  688. }
  689. // Check for device classification in url and strip it if present
  690. if ($this->getSiteVar('DEVICE_DEBUG')) {
  691. if (preg_match(';^device/([^/]+)/(.*)$;', $path, $matches)) {
  692. $device = $matches[1]; // layout forced by url
  693. $path = $matches[2];
  694. $urlPrefix .= "device/$device/";
  695. $urlDeviceDebugPrefix .= "device/$device/";
  696. $deviceCacheTimeout = null;
  697. } elseif (isset($_GET['_device']) && preg_match(';^device/([^/]+)/$;', $_GET['_device'], $matches)) {
  698. $device = $matches[1];
  699. $urlPrefix .= "device/$device/";
  700. $urlDeviceDebugPrefix .= "device/$device/";
  701. $deviceCacheTimeout = null;
  702. }
  703. }
  704. define('URL_DEVICE_DEBUG_PREFIX', $urlDeviceDebugPrefix);
  705. define('URL_PREFIX', $urlPrefix);
  706. self::log(LOG_DEBUG, "Setting URL_PREFIX to " . URL_PREFIX, "kurogo");
  707. define('FULL_URL_PREFIX', 'http'.(IS_SECURE ? 's' : '').'://'.$this->_getHost().URL_PREFIX);
  708. $this->checkCurrentVersion();
  709. $this->deviceClassifier = new DeviceClassifier($device, $deviceCacheTimeout, $override);
  710. //preserved for compatibility
  711. $GLOBALS['deviceClassifier'] = $this->deviceClassifier;
  712. $this->initTheme();
  713. }
  714. private function initContexts() {
  715. Kurogo::log(LOG_DEBUG, 'Initializing contexts', 'context');
  716. $this->contexts = array();
  717. $this->activeContexts = array();
  718. $contexts = $this->getOptionalSiteSections('contexts');
  719. $contextGroups = array();
  720. foreach ($contexts as $key=>$contextData) {
  721. $context = UserContext::factory($key, $contextData);
  722. $this->contexts[$context->getID()] = $context;
  723. }
  724. Kurogo::log(LOG_DEBUG, 'Contexts: ' . implode(', ', array_keys($this->activeContexts)), 'context');
  725. }
  726. public function setUserContext($key) {
  727. if ($context = $this->getContext($key)) {
  728. if ($context->setContext(true)) {
  729. $this->initContexts();
  730. return true;
  731. } else {
  732. throw new KurogoException("Context $key cannot be set");
  733. }
  734. } else {
  735. throw new KurogoException("Context $key not found");
  736. }
  737. }
  738. public function getContext($key) {
  739. if (!isset($this->contexts)) {
  740. $this->initContexts();
  741. }
  742. return Kurogo::arrayVal($this->contexts, $key);
  743. }
  744. public function getContexts() {
  745. if (!isset($this->contexts)) {
  746. $this->initContexts();
  747. }
  748. return $this->contexts;
  749. }
  750. public function getActiveContexts() {
  751. if (!isset($this->contexts)) {
  752. $this->initContexts();
  753. }
  754. $activeContexts = array();
  755. foreach ($this->contexts as $id=>$context) {
  756. if ($context->isActive() && $context->getID()!=UserContext::CONTEXT_DEFAULT) {
  757. $activeContexts[$id] = $context;
  758. }
  759. }
  760. return $activeContexts;
  761. }
  762. protected function addContext(UserContext $context) {
  763. }
  764. private function loadSites() {
  765. //load sites.ini file
  766. $path = SITES_DIR . DIRECTORY_SEPARATOR . 'sites.ini';
  767. $sitesConfig = $this->baseConfigStore->loadConfig($path, 'file', Config::OPTION_IGNORE_SHARED);
  768. $sitesData = $sitesConfig->getSectionVars();
  769. if (count($sitesData)==0) {
  770. throw new KurogoConfigurationException("No valid sites configured");
  771. }
  772. $sharedData = Kurogo::arrayVal($sitesData, 'shared', array());
  773. unset($sitesData['shared']);
  774. if (!defined('SERVER_KEY')) {
  775. $serverKey = Kurogo::arrayVal($sharedData, 'SERVER_KEY', md5(SITES_DIR));
  776. define('SERVER_KEY', $serverKey);
  777. }
  778. $sites = array();
  779. $multiSite = null;
  780. $default = null;
  781. foreach ($sitesData as $siteName=>$siteData) {
  782. // [shared] section will be applied as common settings for all sites
  783. $siteData = array_merge($sharedData, $siteData);
  784. $site = new KurogoSite($siteName, $siteData);
  785. if ($site->isDefault()) {
  786. if (strlen($default)) {
  787. throw new KurogoConfigurationException("Only 1 site can be labeled default, sites $siteName and $default set to default");
  788. }
  789. $default = $siteName;
  790. }
  791. $sites[$site->getName()] = $site;
  792. }
  793. $this->multiSite = count($sites) > 1;
  794. return $sites;
  795. }
  796. public function getSites() {
  797. $sites = $this->loadSites();
  798. return $sites;
  799. }
  800. //attempt to load kurogo.ini at several known paths
  801. private function loadKurogoConfig() {
  802. $paths = array(
  803. '/etc/kurogo/kurogo.ini',
  804. implode(DIRECTORY_SEPARATOR, array(ROOT_BASE_DIR, 'sites', 'kurogo.ini')),
  805. implode(DIRECTORY_SEPARATOR, array(ROOT_BASE_DIR, 'sites', 'kurogo-local.ini')),
  806. implode(DIRECTORY_SEPARATOR, array(ROOT_DIR, 'config', 'kurogo-local.ini')),
  807. );
  808. foreach ($paths as $path) {
  809. try {
  810. if ($kurogoConfig = $this->baseConfigStore->loadConfig($path, 'file', Config::OPTION_IGNORE_MODE | Config::OPTION_IGNORE_LOCAL | Config::OPTION_IGNORE_SHARED | Config::OPTION_DO_NOT_CREATE)) {
  811. break;
  812. }
  813. } catch (KurogoConfigurationNotFoundException $e) {
  814. }
  815. }
  816. if (!$kurogoConfig instanceOf Config) {
  817. //give a shout out if they are on a old setup
  818. if (file_exists(implode(DIRECTORY_SEPARATOR, array(ROOT_DIR,'config','kurogo.ini')))) {
  819. die("The location of the kurogo.ini file has changed. Please see kurogo.org/docs");
  820. }
  821. $kurogoConfig = new EmptyConfig('kurogo', 'kurogo');
  822. }
  823. return $kurogoConfig;
  824. }
  825. private function initSite(&$path) {
  826. $sites = $this->loadSites();
  827. if (count($sites)==1) {
  828. //there's only one site
  829. $site = current($sites);
  830. $urlBase = rtrim($site->getUrlBase(),'/') . '/';
  831. } elseif (PHP_SAPI == 'cli') {
  832. //path contains -site parameter if included, otherwise use the default site
  833. $site = null;
  834. foreach ($sites as $_site) {
  835. if ( (strlen($path) && $_site->getName()==$path) ||
  836. (strlen($path)==0 && $_site->isDefault())) {
  837. $site = $_site;
  838. break;
  839. }
  840. }
  841. if (!$site) {
  842. if (strlen($path)) {
  843. throw new KurogoConfigurationException("Site $path is not defined in sites.ini");
  844. } else {
  845. throw new KurogoConfigurationException("Unable to determine default site");
  846. }
  847. }
  848. } else {
  849. //multiple sites. A score will be returned. The highest score will be the default
  850. $scores = array();
  851. foreach ($sites as $i=>$site) {
  852. $scores[$i] = $site->getSiteScore($path, SERVER_HOST);
  853. }
  854. $topScores = array_keys($scores, max($scores));
  855. if (count($topScores)==1) {
  856. $site = $sites[current($topScores)];
  857. $urlBase = rtrim($site->getUrlBase(),'/') . '/';
  858. if (strncmp($path, $urlBase, strlen(rtrim($urlBase,'/'))) !==0) {
  859. if (strlen($path)) {
  860. $this->redirectToURL(rtrim($urlBase,'/') . '/' . ltrim($path,'/'));
  861. }
  862. }
  863. } elseif ($path) {
  864. _404();
  865. } else {
  866. throw new KurogoException("Site could not be determined. You should have a default site configured");
  867. }
  868. }
  869. if (!$site instanceOf KurogoSite) {
  870. throw new KurogoException("Site not determined. This is a bug in Kurogo. Please report your sites.ini");
  871. }
  872. $siteDir = realpath($site->getSiteDir());
  873. if (!is_dir($siteDir)) {
  874. throw new KurogoConfigurationException("Site Directory $siteDir not found for site " . $site->getName());
  875. }
  876. $this->site = $site;
  877. if ($cacher = $site->cacher()) {
  878. $this->cacher = $cacher;
  879. }
  880. if ($configMode = $site->getConfigMode()) {
  881. $this->setConfigMode($configMode);
  882. }
  883. define('SITE_NAME', $site->getName());
  884. define('SHARED_DIR', $site->getSharedDir());
  885. define('SHARED_LIB_DIR', SHARED_DIR . DIRECTORY_SEPARATOR . 'lib');
  886. define('SHARED_APP_DIR', SHARED_DIR . DIRECTORY_SEPARATOR . 'app');
  887. define('SHARED_MODULES_DIR', SHARED_APP_DIR . DIRECTORY_SEPARATOR . 'modules');
  888. define('SHARED_DATA_DIR', SHARED_DIR . DIRECTORY_SEPARATOR . 'data');
  889. define('SHARED_CONFIG_DIR', SHARED_DIR . DIRECTORY_SEPARATOR . 'config');
  890. define('SHARED_SCRIPTS_DIR', SHARED_DIR . DIRECTORY_SEPARATOR . 'scripts');
  891. if (PHP_SAPI == 'cli') {
  892. define('URL_BASE', null);
  893. } else {
  894. if ($site->getURLBaseAuto()) {
  895. //verify url base
  896. // @TODO this likely does not make virtual directories (IIS) work yet.
  897. $webroot = $_SERVER['DOCUMENT_ROOT'] . $urlBase;
  898. if (realpath($webroot) != WEBROOT_DIR) {
  899. if (count($sites) == 1) {
  900. throw new KurogoConfigurationException("URL base ($urlBase) does not match detected webroot (" . $webroot . "). Please update sites.ini");
  901. }
  902. }
  903. }
  904. define('URL_BASE', $urlBase);
  905. Kurogo::log(LOG_DEBUG,"Setting site to " . $site->getName() . " with a base of $urlBase", 'kurogo');
  906. // Strips out the leading part of the url for sites where
  907. // the base is not located at the document root, ie.. /mobile or /m
  908. // Also strips off the leading slash (needed by device debug below)
  909. if (isset($path)) {
  910. // Strip the URL_BASE off the path
  911. $baseLen = strlen(URL_BASE);
  912. if ($baseLen && strpos($path, URL_BASE) === 0) {
  913. $path = substr($path, $baseLen);
  914. }
  915. }
  916. }
  917. // Set up defines relative to SITE_DIR
  918. define('SITE_DIR', $siteDir); //already been realpath'd
  919. define('SITE_LIB_DIR', $site->getSiteLibDir());
  920. define('SITE_APP_DIR', $site->getSiteAppDir());
  921. define('SITE_MODULES_DIR', $site->getSiteModulesDir());
  922. define('DATA_DIR', $site->getDataDir());
  923. define('WEB_BRIDGE_DIR', $site->getWebBridgeDir());
  924. define('CACHE_DIR', $site->getCacheDir());
  925. define('LOG_DIR', $site->getLogDir());
  926. define('SITE_CONFIG_DIR', $site->getConfigDir());
  927. define('SITE_DISABLED_DIR', $site->getConfigDisabledDir());
  928. define('SITE_SCRIPTS_DIR', $site->getScriptsDir());
  929. $this->siteConfigStore = $site->getConfigStore();
  930. define('REDIRECT_ON_EXCEPTIONS', $this->getOptionalSiteVar('REDIRECT_ON_EXCEPTIONS', true, 'error_handling_and_debugging'));
  931. // attempt to load site key
  932. $siteKey = $this->getOptionalSiteVar('SITE_KEY', md5($siteDir));
  933. define('SITE_KEY', $siteKey);
  934. define('SITE_VERSION', $this->getSiteVar('SITE_VERSION', 'site settings'));
  935. define('SITE_BUILD', $this->getSiteVar('SITE_BUILD', 'site settings'));
  936. if ($this->getOptionalSiteVar('SITE_DISABLED')) {
  937. throw new KurogoConfigurationException("Site disabled");
  938. }
  939. return $site;
  940. }
  941. protected function initTheme() {
  942. // Set up theme define
  943. if ($theme = $this->getOptionalSiteVar('ACTIVE_THEME')) {
  944. $themeDir = SITE_DIR . DIRECTORY_SEPARATOR . 'themes' . DIRECTORY_SEPARATOR . $theme;
  945. define('THEME_DIR', $themeDir);
  946. define('SHARED_THEME_DIR', SHARED_DIR . DIRECTORY_SEPARATOR . 'themes' . DIRECTORY_SEPARATOR . $theme);
  947. Kurogo::log(LOG_DEBUG,"Setting theme to $theme.", 'kurogo');
  948. } else {
  949. define('THEME_DIR', null);
  950. define('SHARED_THEME_DIR', null);
  951. }
  952. }
  953. public static function getCharset() {
  954. return Kurogo::sharedInstance()->charset();
  955. }
  956. public function setCharset($charset) {
  957. $this->charset = $charset;
  958. }
  959. public function charset() {
  960. return $this->charset;
  961. }
  962. public static function encrypt($string, $key=SITE_KEY) {
  963. if (strlen($string)==0) {
  964. return $string;
  965. }
  966. if (!function_exists('mcrypt_encrypt')) {
  967. throw new KurogoException("mcrypt functions not available");
  968. }
  969. return base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, md5($key), $string, MCRYPT_MODE_CBC, md5(md5($key))));
  970. }
  971. public static function decrypt($encrypted, $key=SITE_KEY) {
  972. if (strlen($encrypted)==0) {
  973. return $encrypted;
  974. }
  975. if (!function_exists('mcrypt_decrypt')) {
  976. throw new KurogoException("mcrypt functions not available");
  977. }
  978. return rtrim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, md5($key), base64_decode($encrypted), MCRYPT_MODE_CBC, md5(md5($key))), "\0");
  979. }
  980. public function getLanguages() {
  981. return $this->languages;
  982. }
  983. public function setLanguages($languages) {
  984. $validLanguages = self::getAvailableLanguages();
  985. if (is_array($languages)) {
  986. $this->languages = array();
  987. foreach ($languages as $language) {
  988. if (!array_key_exists($language, $validLanguages)) {
  989. throw new KurogoConfigurationException("Invalid language $language");
  990. }
  991. $this->languages[] = $language;
  992. }
  993. } elseif (array_key_exists($languages, $validLanguages)) {
  994. $this->languages[] = $languages;
  995. } else {
  996. throw new KurogoConfigurationException("Invalid language $languages");
  997. }
  998. if (!in_array('en_US', $this->languages)) {
  999. $this->languages[] = "en_US"; // always include english US
  1000. }
  1001. }
  1002. public static function getAvailableLanguages() {
  1003. return array(
  1004. 'af_ZA'=>'Afrikaans',
  1005. 'am_ET'=>'አማርኛ',
  1006. 'be_BY'=>'Беларуская',
  1007. 'bg_BG'=>'български език',
  1008. 'ca_ES'=>'Català',
  1009. 'cs_CZ'=>'čeština',
  1010. 'da_DK'=>'Dansk',
  1011. 'de_AT'=>'Deutsch (Österreich)',
  1012. 'de_CH'=>'Deutsch (Schweiz)',
  1013. 'de_DE'=>'Deutsch (Deutschland)',
  1014. 'el_GR'=>'Ελληνικά',
  1015. 'en_AU'=>'English (Australia)',
  1016. 'en_CA'=>'English (Canada)',
  1017. 'en_GB'=>'English (United Kingdom)',
  1018. 'en_IE'=>'English (Ireland)',
  1019. 'en_NZ'=>'English (New Zealand)',
  1020. 'en_US'=>'English (United States)',
  1021. 'es_ES'=>'Español',
  1022. 'et_EE'=>'Eesti',
  1023. 'eu_ES'=>'Euskara',
  1024. 'fi_FI'=>'Suomi',
  1025. 'fr_BE'=>'Français (Belgique)',
  1026. 'fr_CA'=>'Français (Canada)',
  1027. 'fr_CH'=>'Français (Suisse)',
  1028. 'fr_FR'=>'Français (France)',
  1029. 'he_IL'=>'עברית',
  1030. 'hr_HR'=>'Hrvatski',
  1031. 'hu_HU'=>'Magyar',
  1032. 'hy_AM'=>'Հայերեն',
  1033. 'is_IS'=>'Íslenska',
  1034. 'it_CH'=>'Italiano (Svizzera)',
  1035. 'it_IT'=>'Italiano (Italia)',
  1036. 'ja_JP'=>'日本語',
  1037. 'kk_KZ'=>'Қазақ тілі',
  1038. 'ko_KR'=>'한국어',
  1039. 'lt_LT'=>'Lietuvių',
  1040. 'nl_BE'=>'Vlaams',
  1041. 'nl_NL'=>'Nederlands',
  1042. 'no_NO'=>'Norsk',
  1043. 'pl_PL'=>'Polski',
  1044. 'pt_BR'=>'Português (Brasil)',
  1045. 'pt_PT'=>'Português',
  1046. 'ro_RO'=>'Română',
  1047. 'ru_RU'=>'Pусский',
  1048. 'sk_SK'=>'Slovenčina',
  1049. 'sl_SI'=>'Slovenščina',
  1050. 'sr_YU'=>'Cрпски',
  1051. 'sv_SE'=>'Svenska',
  1052. 'tr_TR'=>'Türkçe',
  1053. 'uk_UA'=>'Yкраїнська',
  1054. 'zh_CN'=>'简体中文',
  1055. 'zh_TW'=>'繁體中文'
  1056. );
  1057. }
  1058. public static function getLifetimeOptions() {
  1059. return array(
  1060. "" => self::getLocalizedString('TIMEOUT_DEFAULT'),
  1061. 0 => self::getLocalizedString('TIMEOUT_NONE'),
  1062. 10 => self::getLocalizedString('TIMEOUT_SECONDS', 10),
  1063. 30 => self::getLocalizedString('TIMEOUT_SECONDS', 30),
  1064. 60 => self::getLocalizedString('TIMEOUT_MINUTE', 1),
  1065. 120 => self::getLocalizedString('TIMEOUT_MINUTES', 2),
  1066. 300 => self::getLocalizedString('TIMEOUT_MINUTES', 5),
  1067. 600 => self::getLocalizedString('TIMEOUT_MINUTES', 10),
  1068. 900 => self::getLocalizedString('TIMEOUT_MINUTES', 15),
  1069. 1800 => self::getLocalizedString('TIMEOUT_MINUTES', 30),
  1070. 3600 => self::getLocalizedString('TIMEOUT_HOUR', 1),
  1071. 7200 => self::getLocalizedString('TIMEOUT_HOURS', 2),
  1072. 10800 => self::getLocalizedString('TIMEOUT_HOURS', 3),
  1073. 21600 => self::getLocalizedString('TIMEOUT_HOURS', 6),
  1074. 43200 => self::getLocalizedString('TIMEOUT_HOURS', 12),
  1075. 86400 => self::getLocalizedString('TIMEOUT_DAY', 1),
  1076. 604800 => self::getLocalizedString('TIMEOUT_WEEK', 1),
  1077. 1209600=> self::getLocalizedString('TIMEOUT_WEEKS', 2),
  1078. 2419200=> self::getLocalizedString('TIMEOUT_WEEKS', 4),
  1079. 15552000=> self::getLocalizedString('TIMEOUT_DAYS', 180),
  1080. 31536000=> self::getLocalizedString('TIMEOUT_YEAR', 1)
  1081. );
  1082. }
  1083. public static function getHashAlgos() {
  1084. return array_combine(hash_algos(), hash_algos());
  1085. }
  1086. /** Config **/
  1087. public static function configStore() {
  1088. return self::sharedInstance()->siteConfigStore;
  1089. }
  1090. public static function getModuleSections($area, $module, $applyContexts=Config::IGNORE_CONTEXTS) {
  1091. return self::sharedInstance()->siteConfigStore->getSections($area, $module, $applyContexts);
  1092. }
  1093. public static function getOptionalModuleSections($area, $module, $applyContexts=Config::IGNORE_CONTEXTS) {
  1094. return self::sharedInstance()->siteConfigStore->getOptionalSections($area, $module, $applyContexts);
  1095. }
  1096. public static function getModuleSection($section, $module, $area='module') {
  1097. return self::sharedInstance()->siteConfigStore->getSection($section, $area, $module);
  1098. }
  1099. public static function getOptionalModuleSection($section, $module, $area='module') {
  1100. return self::sharedInstance()->siteConfigStore->getOptionalSection($section, $area, $module);
  1101. }
  1102. public static function getModuleVar($var, $module, $section=null, $area='module') {
  1103. return self::sharedInstance()->siteConfigStore->getVar($var, $section, $area, $module);
  1104. }
  1105. public static function getOptionalModuleVar($var, $default='', $module, $section=null, $area='module') {
  1106. return self::sharedInstance()->siteConfigStore->getOptionalVar($var, $default, $section, $area, $module);
  1107. }
  1108. public static function getSiteSections($area, $applyContexts=Config::IGNORE_CONTEXTS) {
  1109. return self::sharedInstance()->siteConfigStore->getSections($area, 'site', $applyContexts);
  1110. }
  1111. public static function getOptionalSiteSections($area, $applyContexts=Config::IGNORE_CONTEXTS) {
  1112. return self::sharedInstance()->siteConfigStore->getOptionalSections($area, 'site', $applyContexts);
  1113. }
  1114. public static function getSiteSection($section, $area='site') {
  1115. return self::sharedInstance()->siteConfigStore->getSection($section, $area, 'site');
  1116. }
  1117. public static function getOptionalSiteSection($section, $area='site') {
  1118. return self::sharedInstance()->siteConfigStore->getOptionalSection($section, $area, 'site');
  1119. }
  1120. public static function getSiteVar($var, $section=null, $area='site') {
  1121. return self::sharedInstance()->siteConfigStore->getVar($var, $section, $area, 'site');
  1122. }
  1123. public static function getOptionalSiteVar($var, $default='', $section=null, $area='site') {
  1124. return self::sharedInstance()->siteConfigStore->getOptionalVar($var, $default, $section, $area, 'site');
  1125. }
  1126. /**
  1127. * Returns a string from the site configuration
  1128. * @param string $var the key to retrieve
  1129. * @param string $default an optional default value if the key is not present
  1130. * @return string the value of the string
  1131. */
  1132. public static function getSiteString($var) {
  1133. return self::sharedInstance()->siteConfigStore->getVar($var, 'strings', 'site', 'site');
  1134. }
  1135. public static function getOptionalSiteString($var, $default='') {
  1136. return self::sharedInstance()->siteConfigStore->getOptionalVar($var, $default, 'strings', 'site', 'site');
  1137. }
  1138. public static function getSiteAccessControlListArrays() {
  1139. $acls = array();
  1140. foreach (self::getSiteAccessControlLists() as $acl) {
  1141. $acls[] = $acl->toArray();
  1142. }
  1143. return $acls;
  1144. }
  1145. public static function getSiteAccessControlLists() {
  1146. $aclData = self::getOptionalSiteSections('acls');
  1147. $acls = array();
  1148. foreach ($aclData as $aclArray) {
  1149. if ($acl = AccessControlList::createFromArray($aclArray)) {
  1150. $acls[] = $acl;
  1151. }
  1152. }
  1153. return $acls;
  1154. }
  1155. private function getStringsForLanguage($lang) {
  1156. $stringFiles = array(
  1157. APP_DIR . "/common/strings/".$lang . '.ini',
  1158. SHARED_APP_DIR . "/common/strings/".$lang . '.ini',
  1159. SITE_APP_DIR . "/common/strings/".$lang . '.ini'
  1160. );
  1161. if ($this->module) {
  1162. $stringFiles[] = MODULES_DIR . '/' . $this->module->getID() ."/strings/".$lang . '.ini';
  1163. $stringFiles[] = SHARED_MODULES_DIR . '/' . $this->module->getID() ."/strings/".$lang . '.ini';
  1164. $stringFiles[] = SITE_MODULES_DIR . '/' . $this->module->getID() ."/strings/".$lang . '.ini';
  1165. if ($this->module->getID() != $this->module->getConfigModule()) {

Large files files are truncated, but you can click here to view the full file