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

/forum/web-optimizer/libs/php/html.sprites.php

https://github.com/GreyTeardrop/socionicasys-forum
PHP | 276 lines | 241 code | 5 blank | 30 comment | 29 complexity | 6bdd32c7380db3bb032f57e2016a4d3c MD5 | raw file
Possible License(s): AGPL-1.0, LGPL-3.0, MPL-2.0-no-copyleft-exception
  1. <?php
  2. /**
  3. * File from WEBO Site SpeedUp, WEBO Software (http://www.webogroup.com/)
  4. * Parses array of images to dmensions/pathnames. Stores array of CSS rules
  5. * License agreement: http://www.webogroup.com/about/EULA.txt
  6. *
  7. **/
  8. class html_sprites {
  9. /**
  10. * Constructor
  11. * Sets the options and converts
  12. **/
  13. function html_sprites ($imgs, $options, $main) {
  14. $this->options = $options;
  15. $this->main = $main;
  16. if (!class_exists('css_sprites_optimize', false)) {
  17. require($this->options['css']['installdir'] . 'libs/php/css.sprites.optimize.php');
  18. }
  19. /* create CSS Sprites combiner */
  20. $this->optimizer = new css_sprites_optimize(array(
  21. 'root_dir' => $this->options['css']['installdir'],
  22. 'current_dir' => $this->options['page']['cachedir'],
  23. 'html_cache' => $this->options['page']['cachedir'],
  24. 'website_root' => $this->options['document_root'],
  25. 'truecolor_in_jpeg' => $this->options['css']['truecolor_in_jpeg'],
  26. 'aggressive' => 0,
  27. 'no_ie6' => 0,
  28. 'ignore' => $this->options['css']['css_sprites_ignore'],
  29. 'ignore_list' => $this->options['css']['css_sprites_exclude'],
  30. 'partly' => 0,
  31. 'extra_space' => $this->options['css']['css_sprites_extra_space'],
  32. 'expires_rewrite' => $this->options['css']['css_sprites_expires_rewrite'],
  33. 'cache_images' => $this->options['page']['cache_images'],
  34. 'cache_images_rewrite' => $this->options['page']['far_future_expires_rewrite'],
  35. 'data_uris' => 0,
  36. 'data_uris_separate' => 0,
  37. 'data_uris_size' => 0,
  38. 'data_uris_ignore_list' => '',
  39. 'mhtml' => 0,
  40. 'mhtml_size' => 0,
  41. 'mhtml_ignore_list' => '',
  42. 'css_url' => '',
  43. 'dimensions_limited' => $this->options['page']['dimensions_limited'] ? $this->options['page']['dimensions_limited'] : 10000,
  44. 'no_css_sprites' => 0,
  45. 'multiple_hosts' => empty($this->options['page']['parallel']) ?
  46. array() : explode(" ", $this->options['page']['parallel_hosts']),
  47. 'user_agent' => $this->main->ua_mod,
  48. 'punypng' => $this->options['css']['punypng'],
  49. 'restore_properties' => 0,
  50. 'ftp_access' => $this->options['page']['parallel_ftp'],
  51. 'http_host' => $this->options['page']['host'],
  52. 'https_host' => $this->options['page']['parallel_https'],
  53. 'uniform_cache' => $this->options['uniform_cache']
  54. ));
  55. /* calculate all dimensions for images */
  56. $this->images = $this->get_images_dimensions($imgs);
  57. ksort($this->images);
  58. $this->css = array(42 => array());
  59. $this->css_images = array();
  60. }
  61. /**
  62. /* Main function to process with images
  63. /*
  64. **/
  65. function process ($content) {
  66. $str = '';
  67. $equal = 1;
  68. $exclude_list = explode(" ", $this->options['css']['css_sprites_exclude']);
  69. /* calculate styles */
  70. foreach ($this->images as $url => $image) {
  71. $width = $image[0];
  72. $height = $image[1];
  73. $class = $image[2];
  74. $active = empty($image[3]) ? 0 : $image[3];
  75. $filename = $this->options['document_root'] . $url;
  76. $name = preg_replace("@.*/@", "", $url);
  77. /* skip big images */
  78. if ($width <= $this->options['page']['dimensions_limited'] &&
  79. $height <= $this->options['page']['dimensions_limited'] &&
  80. $width && $height && !empty($class) && !empty($active) &&
  81. ((empty($this->options['css']['css_sprites_ignore']) && !in_array($name, $exclude_list)) ||
  82. (!empty($this->options['css']['css_sprites_ignore']) && in_array($name, $exclude_list)))) {
  83. $this->css_images[$url] = array($filename,
  84. $width, $height, 0, 0, 0, 0, 42, '.' . $class);
  85. $this->css[42]['.' . $class] = array(
  86. 'width' => $width . 'px',
  87. 'height' => $height . 'px',
  88. 'padding' => 0,
  89. 'background-image' => 'url(' . $url . ')',
  90. 'background-repeat' => 'no-repeat'
  91. );
  92. $str .= $url . "_" . $width . "_" . $height;
  93. /* check if all images are equal - this makes Sprite calculation easier */
  94. $w = empty($w) ? $width : $w;
  95. $h = empty($h) ? $height : $h;
  96. $equal = $equal && $w == $width && $h == $height;
  97. }
  98. }
  99. /* skip creating if there is only 1 image */
  100. if (count($this->css_images) > 1) {
  101. $https = empty($_SERVER['HTTPS']) ? '' : 's';
  102. $this->sprite = 'webo.' . md5($str) . '.png';
  103. if (!empty($this->images[$this->sprite . $https])) {
  104. $styles = $this->images[$this->sprite . $https][2];
  105. } else {
  106. $dir = @getcwd();
  107. @chdir($this->options['page']['cachedir']);
  108. $this->optimizer->css_images = array(
  109. $this->sprite => array('images' => $this->css_images)
  110. );
  111. $this->optimizer->css = $this;
  112. $this->optimizer->merge_sprites(4, $this->sprite, $equal && !empty($w) && !empty($h) ? 2 : 1);
  113. $created = 0;
  114. /* check if we have created sprite */
  115. foreach ($this->optimizer->css->css[42] as $class => $rules) {
  116. foreach ($rules as $k => $v) {
  117. if ($k == 'background-image') {
  118. $url = substr($v, 4, strlen($v) - 5);
  119. /* leave this image */
  120. if (empty($this->images[$url])) {
  121. $created = 1;
  122. /* or remove from generated array */
  123. } else {
  124. unset($this->css_images[$url]);
  125. }
  126. }
  127. }
  128. }
  129. @chdir($dir);
  130. if ($created) {
  131. $styles = $this->calculate_styles($this->optimizer->css->css[42]);
  132. } else {
  133. $styles = '';
  134. }
  135. /* cache styles to file */
  136. $this->images[$this->sprite . $https] = array(0, 0, $styles);
  137. $str = '<?php';
  138. foreach ($this->images as $k => $i) {
  139. $str .= "\n" . '$images[\'' . $k .
  140. "'] = array(" . $i[0] . "," . $i[1] . ",'" . $i[2] . "');";
  141. }
  142. $str .= "\n?>";
  143. $this->main->write_file($this->options['page']['cachedir'] . 'wo.img.cache.php', $str);
  144. }
  145. $content = $this->add_styles($content, $styles);
  146. } else {
  147. unset($this->css_images);
  148. }
  149. return $content;
  150. }
  151. /**
  152. * Get dimensions for give array of HTML images
  153. *
  154. **/
  155. function get_images_dimensions ($imgs) {
  156. $images = array();
  157. /* load cached images' dimensions */
  158. @include($this->options['page']['cachedir'] . 'wo.img.cache.php');
  159. /* calculate all dimensions for new images */
  160. if (!empty($imgs)) {
  161. foreach ($imgs as $key => $image) {
  162. if (!empty($this->options['page']['html_tidy']) && ($pos=strpos($image[0], 'src="'))) {
  163. $old_src = substr($image[0], $pos+5, strpos(substr($image[0], $pos+5), '"'));
  164. } elseif (!empty($this->options['page']['html_tidy']) && ($pos=strpos($image[0], "src='"))) {
  165. $old_src = substr($image[0], $pos+5, strpos(substr($image[0], $pos+5), "'"));
  166. } else {
  167. $old_src = preg_replace("!^['\"\s]*(.*?)['\"\s]*$!is", "$1", preg_replace("!.*\ssrc\s*=\s*(\"[^\"]+\"|'[^']+'|[\S]+).*!is", "$1", $image[0]));
  168. }
  169. /* strip GET parameter */
  170. $old_src = ($old_src_param_pos = strpos($old_src, '?')) ? substr($old_src, 0, $old_src_param_pos) : $old_src;
  171. $absolute_src = $this->main->convert_path_to_absolute($old_src,
  172. array('file' => $_SERVER['REQUEST_URI']));
  173. $filename = array_pop(split("/", $absolute_src));
  174. /* fetch only non-cached images */
  175. if (!empty($absolute_src) && (!$this->optimizer->ignore || in_array($filename, $this->optimizer->ignore_list))) {
  176. if (empty($images[$absolute_src])) {
  177. $need_refresh = 1;
  178. $width = $height = 0;
  179. $class = '';
  180. if (strpos($image[0], 'nosprites') === false) {
  181. list($width, $height) = $this->optimizer->get_image(0, '', $absolute_src);
  182. $width = empty($width) ? 0 : $width;
  183. $height = empty($height) ? 0 : $height;
  184. /* skip dymanic images, need to download the last... */
  185. $class = preg_match("@\.(ico|gif|jpe?g|bmp|png)$@", $old_src) &&
  186. $width && $height ? 'wo' . md5($absolute_src) : '';
  187. }
  188. $images[$absolute_src] = array($width, $height, $class);
  189. }
  190. $images[$absolute_src][3] =
  191. !empty($this->options['page']['per_page']) ? 1 : 0;
  192. }
  193. /* remember src for calculated images */
  194. $imgs[$key] = $absolute_src;
  195. }
  196. }
  197. if (!empty($need_refresh)) {
  198. /* cache images' dimensions to file */
  199. $str = '<?php';
  200. foreach ($images as $k => $i) {
  201. $str .= "\n" . '$images[\'' . str_replace('//', '/', $k) .
  202. "'] = array(" . round($i[0]) . "," . round($i[1]) . ",'" . $i[2] . "');";
  203. if (empty($this->options['page']['per_page'])) {
  204. $images[$k][3] = 1;
  205. }
  206. }
  207. $str .= "\n?>";
  208. $this->main->write_file($this->options['page']['cachedir'] . 'wo.img.cache.php', $str);
  209. /* or just mark all images as active */
  210. } elseif (empty($this->options['page']['per_page'])) {
  211. foreach ($images as $k => $i) {
  212. $images[$k][3] = 1;
  213. }
  214. }
  215. return $images;
  216. }
  217. /**
  218. * Return HTML Sprites styles
  219. *
  220. **/
  221. function calculate_styles ($css) {
  222. $styles = '';
  223. if (!empty($this->options['page']['parallel'])) {
  224. $hosts = explode(" ", trim($this->options['page']['parallel_hosts']));
  225. if (count($hosts)) {
  226. $host = $hosts[0];
  227. }
  228. if (!empty($_SERVER['HTTPS']) && !empty($this->options['page']['parallel_https'])) {
  229. $host = $this->options['page']['parallel_https'];
  230. }
  231. }
  232. if (!empty($css)) {
  233. /* form final css chunk */
  234. $styles = '<style type="text/css">';
  235. foreach ($css as $class => $rules) {
  236. $styles .= $class . '{';
  237. foreach ($rules as $k => $v) {
  238. if ($k == 'background-image') {
  239. $v = 'url(' .
  240. (empty($host) ?
  241. (empty($this->options['page']['far_future_expires_rewrite']) ?
  242. '' : $this->options['page']['cachedir_relative'] . 'wo.static.php?') .
  243. $this->options['page']['cachedir_relative'] :
  244. '//' . $host . $this->options['page']['cachedir_relative']) .
  245. substr($v, 4);
  246. }
  247. $styles .= $k . ':' . $v . ';';
  248. }
  249. $styles .= '}';
  250. }
  251. $styles = str_replace(';}', '}', $styles) . '</style>';
  252. }
  253. return $styles;
  254. }
  255. /**
  256. * Return HTML with inserted for HTML Sprites styles
  257. *
  258. **/
  259. function add_styles ($content, $styles) {
  260. if (!empty($styles)) {
  261. /* insert css chunk to spot */
  262. $content = str_replace("@@@WSSSTYLES@@@", $styles, $content);
  263. } else {
  264. unset($this->css_images);
  265. }
  266. return $content;
  267. }
  268. }
  269. ?>