PageRenderTime 52ms CodeModel.GetById 26ms RepoModel.GetById 1ms app.codeStats 0ms

/engine.php

https://github.com/microcipcip/LightweightFramework
PHP | 295 lines | 226 code | 32 blank | 37 comment | 101 complexity | 8f6a8826804bed3b4131bcd09c5a818b MD5 | raw file
  1. <?php
  2. // =======================================
  3. // LIGHTWEIGHTFRAMEWORK - Initialization
  4. // =======================================
  5. ob_start();
  6. session_start();
  7. // Define root absolute path
  8. $root = dirname(__FILE__);
  9. // Load configuration
  10. require_once "$root/_config/website.php";
  11. require_once "$root/_config/javascript.php";
  12. // =========================================
  13. // LIGHTWEIGHTFRAMEWORK - Public functions
  14. // =========================================
  15. // Strings escaping (UTF-8 to HTML)
  16. function e($string) {
  17. return htmlentities($string, ENT_COMPAT, 'UTF-8');
  18. }
  19. // Return an HTML menu reading files structure in pages/
  20. function loadMenu($options = null) {
  21. global $root;
  22. global $page;
  23. global $menu;
  24. $menu_local = $menu;
  25. if (!empty($options)) foreach ($options as $k => $s) if ($s != 'inherit') $menu_local[$k] = $s;
  26. return loadMenuRecursion(ls("$root/pages", true, false, true), '', $page, $menu_local);
  27. }
  28. // Returns page content
  29. function loadContent() {
  30. global $content_buffer;
  31. return $content_buffer;
  32. }
  33. // Returns custom section content
  34. function loadSection($name) {
  35. global $root;
  36. global $sections;
  37. extract($GLOBALS, EXTR_SKIP);
  38. if (empty($sections[$name]) || $sections[$name][0] != 'enabled') return;
  39. ob_start();
  40. include "$root/{$sections[$name][1]}";
  41. return ob_get_clean();
  42. }
  43. // Returns HTML inclusion of CSS files
  44. function loadCSS() {
  45. global $root;
  46. global $css_files;
  47. $h = "";
  48. foreach ($css_files as $c) {
  49. $mtime = @filemtime("$root/$c");
  50. if ($mtime) $h .= "<link rel=\"stylesheet\" type=\"text/css\" href=\"$c?t=$mtime\" media=\"all\">\n";
  51. }
  52. return $h;
  53. }
  54. // Returns HTML inclusion of JS files
  55. function loadJS() {
  56. global $root;
  57. global $javascript_files;
  58. buildJS();
  59. $h = "";
  60. foreach ($javascript_files as $j) {
  61. $mtime = @filemtime("$root/$j");
  62. if ($mtime) $h .= "<script src=\"$j?t=$mtime\"></script>\n";
  63. }
  64. return $h;
  65. }
  66. // Re-defines menu options over default ones
  67. function overrideMenuOptions($options, $hereditary = true) {
  68. global $menu;
  69. global $includingParent;
  70. if ($includingParent && !$hereditary) return;
  71. foreach ($options as $k => $s) if ($s != 'inherit') $menu[$k] = $s;
  72. }
  73. // Re-defines sections over default ones
  74. function overrideSections($array, $hereditary = true) {
  75. global $sections;
  76. global $includingParent;
  77. if ($includingParent && !$hereditary) return;
  78. foreach ($array as $k => $s) {
  79. if (!empty($sections[$k])) { // Overrides
  80. if ($s[0] != 'enabled' && $s[0] != 'disabled') $s[0] = $sections[$k][0]; // Inherit enable/disable
  81. if ($s[1] == 'inherit') $s[1] = $sections[$k][1]; // Inherit path
  82. }
  83. $sections[$k] = $s;
  84. }
  85. }
  86. // =========================================
  87. // LIGHTWEIGHTFRAMEWORK - Pages setup
  88. // =========================================
  89. // UTF-8 stuffs
  90. setlocale(LC_CTYPE, 'en_US.utf8');
  91. header('Content-Type: text/html; charset=utf-8');
  92. // Simulate register_globals = Off when it's actived (security)
  93. if (ini_get('register_globals')) {
  94. if (isset($_REQUEST['GLOBALS']) || isset($_FILES['GLOBALS'])) die('GLOBALS overwrite attempt detected');
  95. $urgNoUnset = array('GLOBALS', '_GET', '_POST', '_COOKIE', '_REQUEST', '_SERVER', '_ENV', '_FILES');
  96. $urgInput = array_merge($_GET, $_POST, $_COOKIE, $_SERVER, $_ENV, $_FILES, isset($_SESSION) && is_array($_SESSION) ? $_SESSION : array());
  97. foreach ($urgInput as $k => $v) if (!in_array($k, $urgNoUnset) && isset($GLOBALS[$k])) unset($GLOBALS[$k]);
  98. }
  99. // Perform stripslashes() and trim() on Request data
  100. function striptease(&$arg = null) {
  101. if (is_array($arg)) {
  102. foreach ($arg as $k => $v) striptease($arg[$k]);
  103. } else {
  104. if (!get_magic_quotes_gpc()) $arg = trim($arg);
  105. else $arg = trim(stripslashes($arg));
  106. }
  107. }
  108. striptease($_GET);
  109. striptease($_POST);
  110. striptease($_REQUEST);
  111. // Load page
  112. if (!empty($_GET['page'])) $page = str_replace('/..', '', $_GET['page']); // Remove .. from path for security
  113. ob_start();
  114. $page_path = explode('/', $page);
  115. $includingParent = false;
  116. foreach (array_slice($page_path, 0, -1) as $i => $page_parent) { // For each parent path
  117. $page_parent_folder = "$root/pages/" . implode('/', array_slice($page_path, 0, $i));
  118. foreach (ls($page_parent_folder) as $page_parent_candidate) { // Search for parent file
  119. if ($page_parent . '.' == substr($page_parent_candidate, 0, strlen($page_parent) + 1)) {
  120. $page_parent_path = str_replace('//', '/', $page_parent_folder . '/' . $page_parent_candidate);
  121. ob_start();
  122. $includingParent = true;
  123. include "$page_parent_path"; // Include parent to make configuration overriding
  124. $includingParent = false;
  125. ob_end_clean(); // Discard parent output
  126. }
  127. }
  128. }
  129. $page_file_path = "$root/pages/$page";
  130. if (!is_file($page_file_path . '.php')) { // File not found? Try appending numbers...
  131. for ($i = 0; $i < 100; $i++) for ($j = ''; $j !== '000'; $j .= '0') {
  132. if (is_file($page_file_path . ".$j$i.php")) {
  133. $page_file_path = $page_file_path . ".$j$i";
  134. break 2;
  135. }
  136. }
  137. }
  138. include "$page_file_path.php";
  139. $content_buffer = ob_get_clean(); // Fill page content buffer
  140. // =========================================
  141. // LIGHTWEIGHTFRAMEWORK - Private functions
  142. // =========================================
  143. // Menu recursive builder (used by loadMenu())
  144. function loadMenuRecursion($files, $prefix = '', $active_page, $o, $level = 0, &$active_flag = null) {
  145. $h = '';
  146. if (!is_null($o['max_depth']) && $level >= $o['max_depth']) return $h;
  147. $l = '';
  148. if (!empty($o['1st_level_class']) && $level == 0) $l = ' class="' . $o['1st_level_class'] . '"';
  149. if (!empty($o['2nd_level_class']) && $level == 1) $l = ' class="' . $o['2nd_level_class'] . '"';
  150. $h .= "<{$o['wrapper']}$l>";
  151. $active_flag = false;
  152. uasort($files, 'loadMenuSort');
  153. foreach ($files as $m) {
  154. if (is_array($m)) continue;
  155. $page = parsePageFile("$prefix$m");
  156. if (in_array($page[1], $o['hide_items'])) continue;
  157. $h_children = '';
  158. $active_flag_local = false;
  159. if (!empty($files[$page[0]])) $h_children = loadMenuRecursion($files[$page[0]], $page[1] . '/', $active_page, $o, $level + 1, $active_flag_local);
  160. $active_flag_local = ($active_flag_local && $o['copy_active_class_to_parent']) || $page[1] == $active_page;
  161. $active_flag = $active_flag || $active_flag_local;
  162. $c = $active_flag_local ? ' class="' . $o['active_class'] . '"' : '';
  163. $h .= "<{$o['items']}$c>";
  164. $h .= '<a href="index.php?page=' . e($page[1]) . '">' . $o['pre_html'] . e($page[2]) . $o['post_html'] . '</a>';
  165. $h .= $h_children;
  166. $h .= "</{$o['items']}>";
  167. }
  168. $h .= "</{$o['wrapper']}>";
  169. return $h;
  170. }
  171. // Sort page files (used by loadMenu())
  172. function loadMenuSort($a, $b) {
  173. if (is_array($a)) return 1;
  174. if (is_array($b)) return -1;
  175. $ap = parsePageFile($a);
  176. $bp = parsePageFile($b);
  177. if (empty($ap[3])) $ap[3] = PHP_INT_MAX;
  178. if (empty($bp[3])) $bp[3] = PHP_INT_MAX;
  179. if ($ap[3] == $bp[3]) return strcmp($a, $b);
  180. elseif ($ap[3] >= $bp[3]) return 1;
  181. else return -1;
  182. }
  183. // Build Javascript sources
  184. function buildJS() {
  185. global $root;
  186. global $js_output;
  187. global $js_settings_output;
  188. global $js_sources;
  189. global $js_settings_sources;
  190. // Compute JS sources hash
  191. $hash = '';
  192. foreach ($js_sources as $k => $v) if ($v[0] == 'enabled') $hash .= basename($v[2]) . '/' . filemtime("$root/{$v[2]}") . '/' . filesize("$root/{$v[2]}") . '/';
  193. $hash = md5($hash);
  194. // Read the hash from the current build
  195. $build = md5('');
  196. if (is_file("$root/$js_output")) {
  197. $f = fopen("$root/$js_output", 'r');
  198. $build = substr(fgets($f), 3, 32);
  199. fclose($f);
  200. }
  201. // Build if something changed
  202. if ($hash != $build) {
  203. $f = fopen("$root/$js_output", 'w');
  204. fputs($f, "/* $hash DO NOT ALTER OR MOVE THIS LINE */\n\n\n");
  205. foreach ($js_sources as $k => $v) if ($v[0] == 'enabled') {
  206. fputs($f, "/* [$k] */\n\n");
  207. fputs($f, file_get_contents("$root/{$v[2]}"));
  208. fputs($f, "\n\n/* [/End $k] */\n\n\n");
  209. }
  210. fclose($f);
  211. clearstatcache();
  212. }
  213. // Compute JS settings-hash
  214. $hash = '';
  215. foreach ($js_settings_sources as $k => $v) if ($v[0] == 'enabled' || ($v[0] == 'inherit' && isset($js_sources[$k]) && $js_sources[$k][0] == 'enabled')) $hash .= basename($v[2]) . '/' . filemtime("$root/{$v[2]}") . '/' . filesize("$root/{$v[2]}") . '/';
  216. $hash = md5($hash);
  217. // Read the settings-hash from the current build
  218. $build = md5('');
  219. if (is_file("$root/$js_settings_output")) {
  220. $f = fopen("$root/$js_settings_output", 'r');
  221. $build = substr(fgets($f), 3, 32);
  222. fclose($f);
  223. }
  224. // Build if something changed
  225. if ($hash != $build) {
  226. $f = fopen("$root/$js_settings_output", 'w');
  227. fputs($f, "/* $hash DO NOT ALTER OR MOVE THIS LINE */\n\n\n");
  228. fputs($f, "$(document).ready(function(){\n\n");
  229. foreach ($js_settings_sources as $k => $v) if ($v[0] == 'enabled' || ($v[0] == 'inherit' && isset($js_sources[$k]) && $js_sources[$k][0] == 'enabled')) {
  230. fputs($f, "/* [$k] */\n");
  231. fputs($f, file_get_contents("$root/{$v[2]}"));
  232. fputs($f, "\n/* [/End $k] */\n\n");
  233. }
  234. fputs($f, "});\n");
  235. fclose($f);
  236. clearstatcache();
  237. }
  238. }
  239. // List files in a directory (used by loadMenu())
  240. function ls($path, $show_folders = false, $show_hidden = false, $recursive = false) {
  241. $ls = array();
  242. if (($dh = @opendir($path)) === false) return $ls;
  243. $path = substr($path, -1) == '/' ? $path : $path . '/';
  244. while (($file = readdir($dh)) !== false) {
  245. if (!$show_hidden) if (substr($file, 0, 1) == '.') continue;
  246. if (!$show_folders) if (is_dir($path.$file)) continue;
  247. if ($recursive && ($file != '.') && ($file != '..') && is_dir($path.$file)) $ls[$file] = ls($path.$file, $show_folders, $show_hidden, $recursive);
  248. else $ls[] = $file;
  249. }
  250. return $ls;
  251. }
  252. // Parse a page file retrieving page name, full name, title and sorting (used by loadMenu() and page inclusion)
  253. function parsePageFile($path) {
  254. if (is_array($path)) {
  255. $ret = array();
  256. foreach ($path as $p) $ret[] = parsePageFile($p);
  257. } else {
  258. $m = array();
  259. preg_match('|^(.+/)?([^/.]+)(?:\\.([0-9]+))?\\.php$|', $path, $m);
  260. return @array($m[2], $m[1] . $m[2], ucfirst(trim(str_replace("_", " ", $m[2]))), intval($m[3]));
  261. }
  262. }
  263. ?>