PageRenderTime 57ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 0ms

/src/lib/generator.php

http://prails.googlecode.com/
PHP | 414 lines | 334 code | 47 blank | 33 comment | 75 complexity | 3adf1267cebab371bfb4fe54428587a3 MD5 | raw file
Possible License(s): GPL-3.0, LGPL-2.1
  1. <?php
  2. /**
  3. PRails Web Framework
  4. Copyright (C) 2010 Robert Kunze
  5. This program is free software: you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation, either version 3 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program. If not, see <http://www.gnu.org/licenses/>.
  15. */
  16. class Generator {
  17. static $obj_instance;
  18. var $str_template;
  19. var $str_title;
  20. var $str_description;
  21. var $arr_keywords;
  22. var $str_navigation;
  23. var $str_currentLanguage;
  24. var $obj_lang;
  25. var $arr_styles;
  26. var $arr_noCacheStyles;
  27. var $arr_header;
  28. var $arr_js;
  29. var $arr_noCacheJS;
  30. var $int_time;
  31. var $obj_mod;
  32. var $bol_isCachable;
  33. var $bol_isAjax;
  34. var $str_cacheId;
  35. function Generator() {
  36. $this->int_time = 0;
  37. $this->str_template = DEFAULT_TEMPLATE;
  38. $this->str_title = "";
  39. $this->arr_styles = Array ();
  40. $this->arr_js = Array ();
  41. $this->arr_header = Array();
  42. $this->obj_lang = null;
  43. $this->bol_isCachable = false;
  44. $this->arr_noCacheStyles = Array();
  45. $this->arr_noCacheJS = Array();
  46. }
  47. static function getInstance() {
  48. if (Generator :: $obj_instance) {
  49. return Generator :: $obj_instance;
  50. } else {
  51. Generator :: $obj_instance = new Generator();
  52. return Generator :: $obj_instance;
  53. }
  54. }
  55. function setIsCachable($bol_cachable = true) {
  56. $this->bol_isCachable = $bol_cachable;
  57. }
  58. function setIsAjax($bol_ajax = true) {
  59. $this->bol_isAjax = $bol_ajax;
  60. }
  61. function setLanguage($lang) {
  62. global $currentLang;
  63. $this->obj_lang = new LangData($lang);
  64. $currentLang = $this->obj_lang;
  65. }
  66. function getLanguage() {
  67. return $this->obj_lang;
  68. }
  69. function setCacheId($id) {
  70. $this->str_cacheId = $id;
  71. if (!is_dir("cache/".$id)) {
  72. mkdir("cache/".$id);
  73. }
  74. }
  75. function generateOutput($str_content) {
  76. if ($_SERVER["REQUEST_METHOD"] == "POST") $this->bol_isCachable = false;
  77. if ($this->bol_isAjax) {
  78. if (strlen($this->str_cacheId) > 0) {
  79. $cacheFile = "cache/page_".$this->str_cacheId.md5($_SERVER["SERVER_NAME"].$_SERVER["REQUEST_URI"]).".".$this->obj_lang->language_id;
  80. } else {
  81. $cacheFile = "cache/page_".md5($_SERVER["SERVER_NAME"].$_SERVER["REQUEST_URI"]).".".$this->obj_lang->language_id;
  82. }
  83. $content = $str_content;
  84. $content = str_replace("<!!", "<"."?", $content);
  85. $content = str_replace("!!>", "?".">", $content);
  86. $fp = fopen($cacheFile, "w+");
  87. fwrite($fp, $content);
  88. fclose($fp);
  89. // continue interpretion of code... (post processing of session data)
  90. // eval everything that is between <!! and !!>
  91. if (file_exists($cacheFile)) require($cacheFile);
  92. if (!$this->bol_isCachable) {
  93. @unlink($cacheFile);
  94. }
  95. if (PROFILING_ENABLED === true) {
  96. global $profiler;
  97. $profiler->logEvent("page_no_cache_hit#".$_SERVER["REQUEST_URI"]);
  98. }
  99. session_write_close();
  100. die();
  101. } else {
  102. ob_start();
  103. require ($this->str_template);
  104. $content = ob_get_contents();
  105. ob_end_clean();
  106. $content = str_replace("<!!", "<"."?", $content);
  107. $content = str_replace("!!>", "?".">", $content);
  108. if ($this->bol_isCachable) {
  109. if (strlen($this->str_cacheId) > 0) {
  110. $cacheFile = "cache/page_".$this->str_cacheId.md5($_SERVER["SERVER_NAME"].$_SERVER["REQUEST_URI"]).".".$this->obj_lang->language_id;
  111. } else {
  112. $cacheFile = "cache/page_".md5($_SERVER["SERVER_NAME"].$_SERVER["REQUEST_URI"]).".".$this->obj_lang->language_id;
  113. }
  114. $fp = fopen($cacheFile, "w+");
  115. fwrite($fp, $content);
  116. fclose($fp);
  117. // continue interpretion of code... (post processing of session data)
  118. // eval everything that is between <!! and !!>
  119. if (file_exists($cacheFile))
  120. require($cacheFile);
  121. } else {
  122. $name = tempnam(realpath("cache"), time());
  123. $fp = fopen($name, "w+");
  124. fwrite($fp, $content);
  125. fclose($fp);
  126. // continue interpretion of code... (post processing of session data)
  127. // eval everything that is between <!! and !!>
  128. require($name);
  129. @unlink($name);
  130. session_write_close();
  131. }
  132. }
  133. }
  134. function removeCache($str_path, $bol_subsites = false)
  135. {
  136. $dp = opendir("cache/");
  137. while (($file=readdir($dp)) !== false)
  138. {
  139. $isCurrent = strpos($file, md5($str_path)) == (strlen($file) - strlen(md5($str_path)));
  140. @unlink("cache/".$file);
  141. }
  142. closedir($dp);
  143. }
  144. function parseApplyLanguage($buffer) {
  145. preg_match_all("/\\{([a-zA-Z0-9]+\\.[a-zA-Z0-9.]+)(\\\$?)\\}/", $buffer, $arr_matches);
  146. foreach ($arr_matches[1] as $key => $str_match) {
  147. if (strpos($buffer, "{".$str_match.(strlen($arr_matches[2][$key]) > 0 ? '$' : '')."}") !== false) {
  148. $text = $this->obj_lang->getText($str_match);
  149. if (ENV_PRODUCTION != true && strlen($arr_matches[2][$key])<=0) {
  150. $text = "<!--[LANG:".$str_match."]-->" . $text . "<!--[/LANG:".$str_match."]-->";
  151. }
  152. $buffer = str_replace($arr_matches[0][$key], $text, $buffer);
  153. }
  154. }
  155. return $buffer;
  156. }
  157. /**
  158. * concept ideas for new caching algorithm:
  159. * - definition of data sinks (=event)
  160. * - when change event for certain data occurs, data sink is used to re-generate the templates
  161. * - sub templates are also cached
  162. *
  163. */
  164. function includeTemplate($str_name, $arr_param = null, $bol_parseLanguage = true) {
  165. $startTime = time()+microtime();
  166. $nname = "cache/".md5($str_name);
  167. $tl = new TagLib($str_name);
  168. $str_content = $tl->compile(file_get_contents($str_name));
  169. if (!file_put_contents($nname, $str_content, LOCK_EX)) {
  170. global $log;
  171. $log->fatal("Unable to create cache entry! Please enable write access to all files and folders within the Prails directory.");
  172. }
  173. unset($str_content, $tl);
  174. ob_start();
  175. require ($nname);
  176. $str_content = ob_get_contents();
  177. ob_end_clean();
  178. @unlink($nname);
  179. unset($nname);
  180. if ($bol_parseLanguage) {
  181. $str_content = $this->parseApplyLanguage($str_content);
  182. }
  183. $endTime = time()+microtime();
  184. if (substr(basename($str_name), -5) == ".html" || substr(basename($str_name), -4) == ".xml" ) {
  185. $str_content = "<!-- TEMPLATE " . $str_name . " (".round($endTime - $startTime, 4)."s) -->\n" . $str_content."\n<!-- END TEMPLATE ".$str_name." -->\n";
  186. }
  187. return $str_content;
  188. }
  189. function setTitle($str_title, $bol_override = true) {
  190. if ($bol_override || strlen($this->str_title) == 0)
  191. $this->str_title = $str_title;
  192. }
  193. function getTitle() {
  194. return $this->str_title;
  195. }
  196. function setDescription($str_desc, $bol_override = true) {
  197. if ($bol_override || strlen($this->str_description) == 0)
  198. $this->str_description = $str_desc;
  199. }
  200. function getDescription() {
  201. return $this->str_description;
  202. }
  203. function setKeywords($mixed) {
  204. $this->arr_keywords = Array();
  205. if (is_array($mixed))
  206. {
  207. $this->arr_keywords = array_merge($this->arr_keywords, $mixed);
  208. } else {
  209. array_push($this->arr_keywords, $mixed);
  210. }
  211. }
  212. function getKeywords() {
  213. $str_k = "";
  214. foreach ($this->arr_keywords as $str_keyword) {
  215. if (strlen($str_k) > 0) $str_k .= ",";
  216. $str_k .= $str_keyword;
  217. }
  218. return $str_k;
  219. }
  220. function getStyleSheets() {
  221. global $SERVER;
  222. $str_styles = "";
  223. $time = time();
  224. $styles = Array();
  225. foreach ($this->arr_styles as $style) {
  226. if ($style["browser"] == "all" && file_exists($style["path"])) {
  227. array_push($styles, $style["path"]);
  228. } else if ($style["browser"] == "all" && !file_exists($style["path"])) {
  229. array_push($this->arr_noCacheStyles, $style);
  230. }
  231. }
  232. $cssLib = new CSSLib($styles);
  233. $cssLib->cleanOldCache();
  234. $path = $cssLib->mergeStyles(ENV_PRODUCTION === true, CSS_EMBED_RESOURCES);
  235. $str_styles .= "<link rel='stylesheet' type='text/css' media='screen' href='".str_replace('http:', '', $SERVER).$path."' />\n";
  236. $str_styles .= "<!--[if lte IE 7]><link rel='stylesheet' media='screen' href='".str_replace('http:', '', $SERVER).str_replace(".css", ".header.css", $path)."' /><![endif]-->";
  237. if (is_array($this->arr_noCacheStyles)) foreach ($this->arr_noCacheStyles as $ncs) {
  238. $str_styles .= "<link rel='stylesheet' media='".$ncs["media"]."' href='".$ncs["path"]."' />\n";
  239. }
  240. foreach ($this->arr_styles as $style) {
  241. if ($style["browser"] != "all") {
  242. if ($style["browser"] == "IE")
  243. {
  244. $str_styles .= "<!--[if IE]>\n";
  245. $str_styles .= "<link rel='stylesheet' media='" . $style["media"] . "' href='" . $style["path"] . "' />\n";
  246. $str_styles .= "<![endif]-->";
  247. } else if (is_array($style["browser"])) {
  248. $str_styles .= "<!--[if ".$style["browser"]["operator"]." IE ".$style["browser"]["version"]."]>\n";
  249. $str_styles .= "<link rel='stylesheet' media='" . $style["media"] . "' href='" . $style["path"] . "' />\n";
  250. $str_styles .= "<![endif]-->";
  251. } else {
  252. $str_styles .= "<![if !IE]>\n";
  253. $str_styles .= "<link rel='stylesheet' media='" . $style["media"] . "' href='" . $style["path"] . "' />\n";
  254. $str_styles .= "<![endif]>";
  255. }
  256. }
  257. }
  258. return $str_styles;
  259. }
  260. function addStyleSheet($path, $media = "screen", $browser = "all") {
  261. // check if stylesheet has already been loaded
  262. if ($media === false || in_array(substr($path, 0, 6), Array("http:/", "https:", "ftp://"))) {
  263. foreach ($this->arr_noCacheStyles as $arr_style) {
  264. if ($path == $arr_style["path"])
  265. return;
  266. }
  267. array_push($this->arr_noCacheStyles, Array (
  268. "media" =>"screen",
  269. "path" => $path,
  270. "browser"=> $browser
  271. ));
  272. } else {
  273. foreach ($this->arr_styles as $arr_style) {
  274. if ($path == $arr_style["path"])
  275. return;
  276. }
  277. array_push($this->arr_styles, Array (
  278. "media" => ($media === true ? "screen" : $media),
  279. "path" => $path,
  280. "browser"=> $browser
  281. ));
  282. }
  283. }
  284. function getJavaScripts() {
  285. global $SERVER;
  286. $str_js = "";
  287. $time = time();
  288. $prefix = md5(implode("", $this->arr_js));
  289. $dp = opendir("cache/");
  290. while (($file = readdir($dp)) !== false) {
  291. if (strpos($file, $prefix) !== false) {
  292. $points = explode(".", $file);
  293. $time = (int)$points[1];
  294. break;
  295. }
  296. }
  297. foreach ($this->arr_js as $js) {
  298. if (@filectime($js) > $time) {
  299. // we need to regenerate the javascript files
  300. @unlink("cache/".$prefix.".".$time.".js");
  301. if (file_exists("cache/".$prefix.".".$time.".jsgz")) {
  302. @unlink("cache/".$prefix.".".$time.".jsgz");
  303. }
  304. $time = time();
  305. break;
  306. }
  307. }
  308. $path = "cache/".$prefix.".".$time.".js";
  309. if (!file_exists($path)) {
  310. $fp = fopen($path, "w+");
  311. $gp = gzopen(str_replace(".js", ".jsgz", $path), "w9");
  312. $gzData = "";
  313. foreach ($this->arr_js as $js) {
  314. if (file_exists($js)) {
  315. $str = file_get_contents($js)."\n";
  316. if (ENV_PRODUCTION === true) {
  317. $str = JSMIN::minify($str);
  318. }
  319. fwrite($fp, $str);
  320. gzwrite($gp, $str);
  321. } else {
  322. if (!is_array($this->arr_noCacheJS)) $this->arr_noCacheJS = Array();
  323. array_push($this->arr_noCacheJS, $js);
  324. }
  325. }
  326. fclose($fp);
  327. gzclose($gp);
  328. @chmod($path, 0755);
  329. @chmod(str_replace(".js", ".jsgz", $path), 0755);
  330. }
  331. $str_js .= "<script src='" . str_replace('http:', '', $SERVER).$path . "' type='text/javascript'></script>\n";
  332. if (is_array($this->arr_noCacheJS)) {
  333. foreach ($this->arr_noCacheJS as $ncjs) {
  334. $str_js .= "<script src='" . $ncjs . "' type='text/javascript'></script>\n";
  335. }
  336. }
  337. return $str_js;
  338. }
  339. function addJavaScript($path, $toCache = true) {
  340. // check if stylesheet has already been loaded
  341. if ($toCache) {
  342. if (!in_array($path, $this->arr_js)) {
  343. array_push($this->arr_js, $path);
  344. }
  345. } else {
  346. if (!in_array($path, $this->arr_noCacheJS)) {
  347. array_push($this->arr_noCacheJS, $path);
  348. }
  349. }
  350. }
  351. function getHeaders() {
  352. $str_headers = "";
  353. foreach ($this->arr_header as $header) {
  354. $str_headers .= $header;
  355. }
  356. return $str_headers;
  357. }
  358. function addHeader($str_header) {
  359. if (!in_array($str_header, $this->arr_header)) {
  360. array_push($this->arr_header, $str_header);
  361. }
  362. }
  363. }
  364. ?>