system.php 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479
  1. <?php
  2. ////////////////////////////////////////////////////////////////////////////////
  3. // Copyright (C) ReloadCMS Development Team //
  4. // http://reloadcms.com //
  5. // //
  6. // This program is distributed in the hope that it will be useful, //
  7. // but WITHOUT ANY WARRANTY, without even the implied warranty of //
  8. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. //
  9. // //
  10. // This product released under GNU General Public License v2 //
  11. ////////////////////////////////////////////////////////////////////////////////
  12. /**
  13. * RCMS basic system modules initialization class
  14. */
  15. class rcms_system extends rcms_user {
  16. /**
  17. * Current language
  18. *
  19. * @var string
  20. */
  21. public $language = '';
  22. /**
  23. * Current skin
  24. *
  25. * @var string
  26. */
  27. public $skin = '';
  28. /**
  29. * Basic framework configuration as key=>value
  30. *
  31. * @var array
  32. */
  33. public $config = array();
  34. /**
  35. * Hmmmm. Maybe its used in i18n engine.. or in user auth...
  36. *
  37. * @var array
  38. */
  39. public $results = array();
  40. /**
  41. * Contains available languages paths etc
  42. *
  43. * @var array
  44. */
  45. public $data = array();
  46. /**
  47. * Contains preloaded modules definitions
  48. *
  49. * @var array
  50. */
  51. public $modules = array();
  52. /**
  53. * Contains default custom language cookie name
  54. *
  55. * @var string
  56. */
  57. public $cookie_lang = 'reloadcms_lang';
  58. /**
  59. * Contains default custom skin cookie name
  60. *
  61. * @var string
  62. */
  63. public $cookie_skin = 'reloadcms_skin';
  64. /**
  65. * Something like system output buffers for different menupoints
  66. *
  67. * @var array
  68. */
  69. public $output = array('modules' => array(), 'menus' => array());
  70. /**
  71. * Contains current output menupoint
  72. *
  73. * @var string
  74. */
  75. public $current_point = '';
  76. /**
  77. * Framework logging path
  78. *
  79. * @var string
  80. */
  81. public $logging = LOGS_PATH;
  82. /**
  83. * Use gzip for logs archieving flag
  84. *
  85. * @var bool
  86. */
  87. public $logging_gz = true;
  88. /**
  89. * Current request URL there
  90. *
  91. * @var string
  92. */
  93. public $url = '';
  94. /**
  95. * Navigation modifiers here
  96. *
  97. * @var array
  98. */
  99. public $navmodifiers = array();
  100. /**
  101. * Doin something awful
  102. *
  103. * @global array $lang
  104. * @param string $language_select_form
  105. * @param string $skin_select_form
  106. *
  107. * @return void
  108. */
  109. public function __construct($language_select_form = '', $skin_select_form = '') {
  110. global $lang;
  111. if (!$language_select_form) {
  112. $language_select_form = '';
  113. }
  114. // Loading configuration
  115. $this->config = parse_ini_file(CONFIG_PATH . 'config.ini');
  116. if (empty($this->config['site_url'])) {
  117. $this->url = 'http://' . $_SERVER['HTTP_HOST'] . dirname($_SERVER['SCRIPT_NAME'] . basename($_SERVER['SCRIPT_NAME'])) . '/';
  118. } else {
  119. $this->url = $this->config['site_url'];
  120. }
  121. if (substr($this->url, -1) != '/') {
  122. $this->url .= '/';
  123. }
  124. $this->language = $this->config['default_lang'];
  125. $this->skin = $this->config['default_skin'];
  126. $this->initialiseLanguage(basename($language_select_form));
  127. $this->logging_gz = extension_loaded('zlib');
  128. if (!empty($this->config['allowchskin'])) {
  129. if (!empty($_COOKIE[$this->cookie_skin]) && is_string($_COOKIE[$this->cookie_skin]) && is_file(SKIN_PATH . basename($_COOKIE[$this->cookie_skin]) . '/skin.general.php'))
  130. $this->skin = basename($_COOKIE[$this->cookie_skin]);
  131. if (!empty($skin_select_form) && is_file(SKIN_PATH . basename($skin_select_form) . '/skin.general.php')) {
  132. $this->skin = $skin_select_form;
  133. setcookie($this->cookie_skin, basename($skin_select_form), FOREVER_COOKIE);
  134. }
  135. }
  136. define('CUR_SKIN_PATH', SKIN_PATH . $this->skin . '/');
  137. $this->initialiseModules();
  138. $this->initializeUser();
  139. }
  140. /**
  141. * Loads current locale
  142. *
  143. * @global array $lang
  144. * @param string $language
  145. * @param bool $default
  146. *
  147. * @return void
  148. */
  149. protected function initialiseLanguage($language = '', $default = false) {
  150. global $lang;
  151. // Loading avaible languages lists
  152. $langs = rcms_scandir(LANG_PATH);
  153. foreach ($langs as $lng) {
  154. if (is_dir(LANG_PATH . $lng) && is_file(LANG_PATH . $lng . '/langid.txt')) {
  155. $lngdata = file(LANG_PATH . $lng . '/langid.txt');
  156. $this->data['languages'][preg_replace("/[\n\r]+/", '', $lngdata[1])] = preg_replace("/[\n\r]+/", '', $lngdata[0]);
  157. $this->data['langpath'][preg_replace("/[\n\r]+/", '', $lngdata[1])] = LANG_PATH . $lng . '/';
  158. }
  159. }
  160. if (!empty($this->config['allowchlang']) && !$default) {
  161. if (!empty($language) && !empty($this->data['languages'][$language])) {
  162. $this->language = $language;
  163. setcookie($this->cookie_lang, $language, FOREVER_COOKIE);
  164. $_COOKIE[$this->cookie_lang] = $language;
  165. } elseif (!empty($_COOKIE[$this->cookie_lang]) && is_string($_COOKIE[$this->cookie_lang]) && !empty($this->data['languages'][basename($_COOKIE[$this->cookie_lang])])) {
  166. $this->language = basename($_COOKIE[$this->cookie_lang]);
  167. } else {
  168. if (!empty($this->config['detect_lang']) && !empty($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
  169. $lang_priority = explode(';', $_SERVER['HTTP_ACCEPT_LANGUAGE']);
  170. $lang_priority = explode(',', $lang_priority[0]);
  171. } else
  172. $lang_priority = array();
  173. foreach ($lang_priority as $lng) {
  174. if ($this->language == $this->config['default_lang'] && !empty($this->data['languages'][basename($lng)])) {
  175. $this->language = basename($lng);
  176. }
  177. }
  178. }
  179. }
  180. if (!is_file($this->data['langpath'][$this->language] . 'langid.txt')) {
  181. die('Language "' . $this->language . '" not found');
  182. }
  183. // Loading language files' list
  184. $lngdir = rcms_scandir($this->data['langpath'][$this->language]);
  185. // Loading language definition
  186. $lngdata = file($this->data['langpath'][$this->language] . 'langid.txt');
  187. $this->config['language'] = preg_replace("/[\n\r]+/", '', $lngdata[1]);
  188. $this->config['encoding'] = preg_replace("/[\n\r]+/", '', $lngdata[2]);
  189. // Loading language bindings
  190. foreach ($lngdir as $langfile) {
  191. if (is_file($this->data['langpath'][$this->language] . $langfile) && $langfile !== 'langid.txt') {
  192. include_once($this->data['langpath'][$this->language] . $langfile);
  193. }
  194. }
  195. }
  196. /**
  197. * Preloads available modules definitions
  198. *
  199. * @param bool $ignore_disable
  200. *
  201. * @return void
  202. */
  203. public function initialiseModules($ignore_disable = false) {
  204. // Loading modules initializations
  205. if (!$ignore_disable) {
  206. if (!$disabled = @parse_ini_file(CONFIG_PATH . 'disable.ini')) {
  207. $disabled = array();
  208. }
  209. } else {
  210. $disabled = array();
  211. }
  212. $modules = rcms_scandir(MODULES_PATH);
  213. foreach ($modules as $module) {
  214. if (empty($disabled[$module]) && is_readable(MODULES_PATH . $module . '/module.php')) {
  215. include_once(MODULES_PATH . $module . '/module.php');
  216. }
  217. }
  218. // Register modules rights in main database
  219. foreach ($this->modules as $type => $modules) {
  220. foreach ($modules as $module => $moduledata) {
  221. foreach ($moduledata['rights'] as $right => $desc) {
  222. $this->rights_database[$right] = $desc;
  223. }
  224. }
  225. }
  226. }
  227. /**
  228. * Appends some custom meta content to global output
  229. *
  230. * @param string $info
  231. *
  232. * @return void
  233. */
  234. public function addInfoToHead($info) {
  235. $this->config['meta'] = @$this->config['meta'] . $info;
  236. }
  237. /**
  238. * Switches current module output point
  239. *
  240. * @param string $point
  241. */
  242. public function setCurrentPoint($point) {
  243. $this->current_point = $point;
  244. }
  245. /**
  246. * Defines new output window in system output buffer
  247. *
  248. * @param string $title
  249. * @param string $data
  250. * @param string $align
  251. *
  252. * @return bool
  253. */
  254. public function defineWindow($title, $data, $align = 'left') {
  255. if ($title == __('Error')) {
  256. $title = '<font color="red">' . $title . '</font>';
  257. }
  258. if ($this->current_point == '__MAIN__') {
  259. $this->output['modules'][] = array($title, $data, $align);
  260. } elseif (!empty($this->current_point)) {
  261. $this->output['menus'][$this->current_point][] = array($title, $data, $align);
  262. } else
  263. return false;
  264. }
  265. /**
  266. * Appends/outputs some window with applied template to output buffer
  267. *
  268. * @param string $title
  269. * @param string $content
  270. * @param string $align
  271. * @param string $template
  272. *
  273. * @return bool
  274. */
  275. public function showWindow($title, $content, $align, $template) {
  276. if ($title == '__NOWINDOW__')
  277. echo $content;
  278. elseif (is_readable($template))
  279. require($template);
  280. else
  281. return false;
  282. return true;
  283. }
  284. /**
  285. * Registers preloaded module. Calls from modules definition in module.php
  286. *
  287. * @param string $module
  288. * @param string $type
  289. * @param string $title
  290. * @param string $copyright
  291. * @param array $rights
  292. *
  293. * @return void
  294. */
  295. public function registerModule($module, $type, $title, $copyright = '', $rights = array()) {
  296. $this->modules[$type][$module]['title'] = $title;
  297. $this->modules[$type][$module]['copyright'] = $copyright;
  298. $this->modules[$type][$module]['rights'] = $rights;
  299. }
  300. /**
  301. * Puts some record to log
  302. *
  303. * @param string $type
  304. * @param string $user
  305. * @param string $message
  306. *
  307. * @return bool
  308. */
  309. public function logPut($type, $user, $message) {
  310. if (!empty($this->config['logging'])) {
  311. $entry = '---------------------------------' . "\n";
  312. $entry .= date('H:i:s d-m-Y', time()) . "\n";
  313. $entry .= $type . ' (' . $user . ' from ' . $_SERVER['REMOTE_ADDR'] . ')' . "\n";
  314. $entry .= $message . "\n";
  315. if ($this->logging_gz) {
  316. gzfile_write_contents($this->logging . date('Y-m-d', time()) . '.log.gz', $entry, 'a');
  317. } else {
  318. file_write_contents($this->logging . date('Y-m-d', time()) . '.log', $entry, 'a');
  319. }
  320. }
  321. return true;
  322. }
  323. /**
  324. * Merges some system logs
  325. *
  326. * @param string $title
  327. * @param int $t_d
  328. * @param int $t_m
  329. * @param int $t_y
  330. * @param int $f_d
  331. * @param int $f_m
  332. * @param int $f_y
  333. *
  334. * @return bool
  335. */
  336. public function logMerge($title, $t_d, $t_m, $t_y, $f_d = 1, $f_m = 1, $f_y = 1980) {
  337. $logs = rcms_scandir($this->logging);
  338. $f = mktime(0, 0, 0, $f_m, $f_d, $f_y);
  339. $t = mktime(0, 0, 0, $t_m, $t_d, $t_y);
  340. $to_merge = array();
  341. foreach ($logs as $log_entry) {
  342. if (preg_match("/^(.*?)-(.*?)-(.*?)\.log(|.gz)$/i", $log_entry, $matches)) {
  343. $c = mktime(0, 0, 0, $matches[2], $matches[3], $matches[1]);
  344. if ($c >= $f && $c <= $t) {
  345. $to_merge[] = $log_entry;
  346. }
  347. }
  348. }
  349. if (!empty($to_merge)) {
  350. if ($this->logging_gz)
  351. $suffix = '.gz';
  352. else
  353. $suffix = '';
  354. $merged_file = $this->logging . $title . '.tar' . $suffix;
  355. $merged = new tar();
  356. $merged->isGzipped = $this->logging_gz;
  357. $merged->filename = $merged_file;
  358. $path = getcwd();
  359. chdir($this->logging);
  360. foreach ($to_merge as $file) {
  361. $merged->addFile($file, substr($file, -3) == '.gz');
  362. }
  363. chdir($path);
  364. if ($merged->saveTar()) {
  365. foreach ($to_merge as $file) {
  366. rcms_delete_files($this->logging . $file);
  367. }
  368. }
  369. }
  370. return true;
  371. }
  372. /**
  373. * Merges system logs by month
  374. *
  375. * @return bool
  376. */
  377. public function logMergeByMonth() {
  378. $logs = rcms_scandir($this->logging);
  379. $d = date('d');
  380. $m = date('m');
  381. $Y = date('Y');
  382. $merged = array();
  383. foreach ($logs as $log_entry) {
  384. if (preg_match("/^(.*?)-(.*?)-(.*?)\.log(|.gz)$/i", $log_entry, $matches)) {
  385. $t = date('t', mktime(0, 0, 0, $matches[2], $matches[3], $matches[1]));
  386. if (!in_array($matches[1] . '-' . $matches[2], $merged) && ($matches[2] != $m || $matches[1] != $Y)) {
  387. $this->logMerge($matches[1] . '-' . $matches[2], $t, $matches[2], $matches[1], 1, $matches[2], $matches[1]);
  388. $merged[] = $matches[1] . '-' . $matches[2];
  389. }
  390. }
  391. }
  392. return true;
  393. }
  394. function registerNavModifier($base, $mod_handler, $help_handler) {
  395. $this->navmodifiers[$base] = array('m' => $mod_handler, 'h' => $help_handler);
  396. return true;
  397. }
  398. }
  399. /**
  400. * Tries to perform string localization with current locale
  401. *
  402. * @global array $lang
  403. * @param string $string
  404. *
  405. * @return string
  406. */
  407. function __($string) {
  408. global $lang;
  409. if (!empty($lang['def'][$string])) {
  410. return $lang['def'][$string];
  411. } else {
  412. return $string;
  413. }
  414. }
  415. /**
  416. * Puts some record into system log
  417. *
  418. * @global object $system
  419. * @param string $type
  420. * @param string $user
  421. * @param string $message
  422. *
  423. * @return bool
  424. */
  425. function rcms_log_put($type, $user, $message) {
  426. global $system;
  427. return $system->logPut($type, $user, $message);
  428. }
  429. /**
  430. * Cuts some string to selected lenght
  431. *
  432. * @param string $str
  433. * @param int $lenght
  434. *
  435. * @return string
  436. */
  437. function cut_text($str, $lenght = 25) {
  438. $str = substr($str, 0, $lenght) . ((strlen($str) > $lenght) ? '...' : '');
  439. return ($str);
  440. }