PageRenderTime 25ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 1ms

/lib/includes/js/tiny_mce/tiny_mce_gzip.php

https://github.com/KenBoyer/CompactCMS
PHP | 332 lines | 160 code | 60 blank | 112 comment | 40 complexity | a48281fe9732363ebcf1a0d9ef46ce6b MD5 | raw file
  1. <?php
  2. /* make sure no-one can run anything here if they didn't arrive through 'proper channels' */
  3. if(!defined("COMPACTCMS_CODE")) { die('Illegal entry point!'); } /*MARKER*/
  4. /**
  5. * tiny_mce_gzip.php
  6. *
  7. * Copyright 2010, Moxiecode Systems AB
  8. * Released under LGPL License.
  9. *
  10. * License: http://tinymce.moxiecode.com/license
  11. * Contributing: http://tinymce.moxiecode.com/contributing
  12. */
  13. // Handle incoming request if it's a script call
  14. if (TinyMCE_Compressor::getParam("js")) {
  15. // Default settings
  16. $tinyMCECompressor = new TinyMCE_Compressor(array(
  17. /*
  18. * Add any site-specific defaults here that you may wish to implement. For example:
  19. *
  20. * "languages" => "en",
  21. * "cache_dir" => realpath(dirname(__FILE__) . "/../../_cache"),
  22. * "files" => "somescript,anotherscript",
  23. * "expires" => "1m",
  24. */
  25. ));
  26. // Handle request, compress and stream to client
  27. $tinyMCECompressor->handleRequest();
  28. }
  29. /**
  30. * This class combines and compresses the TinyMCE core, plugins, themes and
  31. * language packs into one disk cached gzipped request. It improves the loading speed of TinyMCE dramatically but
  32. * still provides dynamic initialization.
  33. *
  34. * Example of direct usage:
  35. * require_once("../tiny_mce_gzip.php");
  36. *
  37. * // Renders script tag with compressed scripts
  38. * TinyMCE_Compressor::renderTag(array(
  39. * "url" => "../tiny_mce_gzip.php",
  40. * "plugins" => "pagebreak,style",
  41. * "themes" => "advanced",
  42. * "languages" => "en"
  43. * ));
  44. */
  45. class TinyMCE_Compressor {
  46. private $files, $settings;
  47. private static $defaultSettings = array(
  48. "plugins" => "",
  49. "themes" => "",
  50. "languages" => "",
  51. "disk_cache" => true,
  52. "expires" => "30d",
  53. "cache_dir" => "",
  54. "compress" => true,
  55. "suffix" => "",
  56. "files" => "",
  57. "source" => false,
  58. );
  59. /**
  60. * Constructs a new compressor instance.
  61. *
  62. * @param Array $settings Name/value array with non-default settings for the compressor instance.
  63. */
  64. public function __construct($settings = array()) {
  65. $this->settings = array_merge(self::$defaultSettings, $settings);
  66. if (empty($this->settings["cache_dir"]))
  67. $this->settings["cache_dir"] = dirname(__FILE__);
  68. }
  69. /**
  70. * Adds a file to the concatenation/compression process.
  71. *
  72. * @param String $path Path to the file to include in the compressed package/output.
  73. */
  74. public function &addFile($file) {
  75. $this->files .= ($this->files ? "," : "") . $file;
  76. return $this;
  77. }
  78. /**
  79. * Handles the incoming HTTP request and sends back a compressed script depending on settings and client support.
  80. */
  81. public function handleRequest() {
  82. $files = array();
  83. $supportsGzip = false;
  84. $expiresOffset = $this->parseTime($this->settings["expires"]);
  85. $tinymceDir = dirname(__FILE__);
  86. // Override settings with querystring params
  87. $plugins = self::getParam("plugins");
  88. if ($plugins)
  89. $this->settings["plugins"] = $plugins;
  90. $plugins = explode(',', $this->settings["plugins"]);
  91. $themes = self::getParam("themes");
  92. if ($themes)
  93. $this->settings["themes"] = $themes;
  94. $themes = explode(',', $this->settings["themes"]);
  95. $languages = self::getParam("languages");
  96. if ($languages)
  97. $this->settings["languages"] = $languages;
  98. $languages = explode(',', $this->settings["languages"]);
  99. $tagFiles = self::getParam("files");
  100. if ($tagFiles)
  101. $this->settings["files"] = $tagFiles;
  102. $diskCache = self::getParam("diskcache");
  103. if ($diskCache)
  104. $this->settings["disk_cache"] = ($diskCache === "true");
  105. $src = self::getParam("src");
  106. if ($src)
  107. $this->settings["source"] = ($src === "true");
  108. // Add core
  109. $files[] = "tiny_mce";
  110. foreach ($languages as $language)
  111. $files[] = "langs/$language";
  112. // Add plugins
  113. foreach ($plugins as $plugin) {
  114. $files[] = "plugins/$plugin/editor_plugin";
  115. foreach ($languages as $language)
  116. $files[] = "plugins/$plugin/langs/$language";
  117. }
  118. // Add themes
  119. foreach ($themes as $theme) {
  120. $files[] = "themes/$theme/editor_template";
  121. foreach ($languages as $language)
  122. $files[] = "themes/$theme/langs/$language";
  123. }
  124. // Add any specified files.
  125. $allFiles = array_merge($files, explode(',', $this->settings['files']));
  126. // Process source files
  127. for ($i = 0; $i < count($allFiles); $i++) {
  128. $file = $allFiles[$i];
  129. if ($this->settings["source"] && file_exists($file . "_src.js")) {
  130. $file .= "_src.js";
  131. } else if (file_exists($file . ".js")) {
  132. $file .= ".js";
  133. } else {
  134. $file = "";
  135. }
  136. $allFiles[$i] = $file;
  137. }
  138. // Generate hash for all files
  139. $hash = md5(implode('', $allFiles));
  140. // Check if it supports gzip
  141. $zlibOn = ini_get('zlib.output_compression') || (ini_set('zlib.output_compression', 0) === false);
  142. $encodings = (isset($_SERVER['HTTP_ACCEPT_ENCODING'])) ? strtolower($_SERVER['HTTP_ACCEPT_ENCODING']) : "";
  143. $encoding = preg_match( '/\b(x-gzip|gzip)\b/', $encodings, $match) ? $match[1] : "";
  144. // Is northon antivirus header
  145. if (isset($_SERVER['---------------']))
  146. $encoding = "x-gzip";
  147. $supportsGzip = $this->settings['compress'] && !empty($encoding) && !$zlibOn && function_exists('gzencode');
  148. // Set cache file name
  149. $cacheFile = $this->settings["cache_dir"] . "/" . $hash . ($supportsGzip ? ".gz" : ".js");
  150. // Set headers
  151. header("Content-type: text/javascript");
  152. header("Vary: Accept-Encoding"); // Handle proxies
  153. header("Expires: " . gmdate("D, d M Y H:i:s", time() + $expiresOffset) . " GMT");
  154. header("Cache-Control: public, max-age=" . $expiresOffset);
  155. if ($supportsGzip)
  156. header("Content-Encoding: " . $encoding);
  157. // Use cached file
  158. if ($this->settings['disk_cache'] && file_exists($cacheFile)) {
  159. readfile($cacheFile);
  160. return;
  161. }
  162. // Set base URL for where tinymce is loaded from
  163. $buffer = "var tinyMCEPreInit={base:'" . dirname($_SERVER["SCRIPT_NAME"]) . "',suffix:''};";
  164. // Load all tinymce script files into buffer
  165. foreach ($allFiles as $file) {
  166. if ($file) {
  167. $fileContents = $this->getFileContents($tinymceDir . "/" . $file);
  168. // $buffer .= "\n//-FILE-$tinymceDir/$file (". strlen($fileContents) . " bytes)\n";
  169. $buffer .= $fileContents;
  170. }
  171. }
  172. // Mark all themes, plugins and languages as done
  173. $buffer .= 'tinymce.each("' . implode(',', $files) . '".split(","),function(f){tinymce.ScriptLoader.markDone(tinyMCE.baseURL+"/"+f+".js");});';
  174. // Compress data
  175. if ($supportsGzip)
  176. $buffer = gzencode($buffer, 9, FORCE_GZIP);
  177. // Write cached file
  178. if ($this->settings["disk_cache"])
  179. @file_put_contents($cacheFile, $buffer);
  180. // Stream contents to client
  181. echo $buffer;
  182. }
  183. /**
  184. * Renders a script tag that loads the TinyMCE script.
  185. *
  186. * @param Array $settings Name/value array with settings for the script tag.
  187. * @param Bool $return The script tag is return instead of being output if true
  188. * @return String the tag is returned if $return is true
  189. */
  190. public static function renderTag($tagSettings, $return = false) {
  191. $settings = array_merge(self::$defaultSettings, $tagSettings);
  192. if (empty($settings["cache_dir"]))
  193. $settings["cache_dir"] = dirname(__FILE__);
  194. $scriptSrc = $settings["url"] . "?js=1";
  195. // Add plugins
  196. if (isset($settings["plugins"]))
  197. $scriptSrc .= "&plugins=" . (is_array($settings["plugins"]) ? implode(',', $settings["plugins"]) : $settings["plugins"]);
  198. // Add themes
  199. if (isset($settings["themes"]))
  200. $scriptSrc .= "&themes=" . (is_array($settings["themes"]) ? implode(',', $settings["themes"]) : $settings["themes"]);
  201. // Add languages
  202. if (isset($settings["languages"]))
  203. $scriptSrc .= "&languages=" . (is_array($settings["languages"]) ? implode(',', $settings["languages"]) : $settings["languages"]);
  204. // Add disk_cache
  205. if (isset($settings["disk_cache"]))
  206. $scriptSrc .= "&diskcache=" . ($settings["disk_cache"] === true ? "true" : "false");
  207. // Add any explicitly specified files if the default settings have been overriden by the tag ones
  208. /*
  209. * Specifying tag files will override (rather than merge with) any site-specific ones set in the
  210. * TinyMCE_Compressor object creation. Note that since the parameter parser limits content to alphanumeric
  211. * only base filenames can be specified. The file extension is assumed to be ".js" and the directory is
  212. * the TinyMCE root directory. A typical use of this is to include a script which initiates the TinyMCE object.
  213. */
  214. if (isset($tagSettings["files"]))
  215. $scriptSrc .= "&files=" .(is_array($settings["files"]) ? implode(',', $settings["files"]) : $settings["files"]);
  216. // Add src flag
  217. if (isset($settings["source"]))
  218. $scriptSrc .= "&src=" . ($settings["source"] === true ? "true" : "false");
  219. $scriptTag = '<script type="text/javascript" src="' . htmlspecialchars($scriptSrc) . '"></script>';
  220. if ($return) {
  221. return $scriptTag;
  222. } else {
  223. echo $scriptTag;
  224. }
  225. }
  226. /**
  227. * Returns a sanitized query string parameter.
  228. *
  229. * @param String $name Name of the query string param to get.
  230. * @param String $default Default value if the query string item shouldn't exist.
  231. * @return String Sanitized query string parameter value.
  232. */
  233. public static function getParam($name, $default = "") {
  234. if (!isset($_GET[$name]))
  235. return $default;
  236. return preg_replace("/[^0-9a-z\-_,]+/i", "", $_GET[$name]); // Sanatize for security, remove anything but 0-9,a-z,-_,
  237. }
  238. /**
  239. * Parses the specified time format into seconds. Supports formats like 10h, 10d, 10m.
  240. *
  241. * @param String $time Time format to convert into seconds.
  242. * @return Int Number of seconds for the specified format.
  243. */
  244. private function parseTime($time) {
  245. $multipel = 1;
  246. // Hours
  247. if (strpos($time, "h") > 0)
  248. $multipel = 3600;
  249. // Days
  250. if (strpos($time, "d") > 0)
  251. $multipel = 86400;
  252. // Months
  253. if (strpos($time, "m") > 0)
  254. $multipel = 2592000;
  255. // Trim string
  256. return intval($time) * $multipel;
  257. }
  258. /**
  259. * Returns the contents of the script file if it exists and removes the UTF-8 BOM header if it exists.
  260. *
  261. * @param String $file File to load.
  262. * @return String File contents or empty string if it doesn't exist.
  263. */
  264. private function getFileContents($file) {
  265. $content = file_get_contents($file);
  266. // Remove UTF-8 BOM
  267. if (substr($content, 0, 3) === pack("CCC", 0xef, 0xbb, 0xbf))
  268. $content = substr($content, 3);
  269. return $content;
  270. }
  271. }
  272. ?>