Source.php 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. <?php
  2. /**
  3. * Class Minify_Source
  4. * @package Minify
  5. */
  6. /**
  7. * A content source to be minified by Minify.
  8. *
  9. * This allows per-source minification options and the mixing of files with
  10. * content from other sources.
  11. *
  12. * @package Minify
  13. * @author Stephen Clay <steve@mrclay.org>
  14. */
  15. class Minify_Source {
  16. /**
  17. * @var int time of last modification
  18. */
  19. public $lastModified = null;
  20. /**
  21. * @var callback minifier function specifically for this source.
  22. */
  23. public $minifier = null;
  24. /**
  25. * @var array minification options specific to this source.
  26. */
  27. public $minifyOptions = null;
  28. /**
  29. * @var string full path of file
  30. */
  31. public $filepath = null;
  32. /**
  33. * @var string HTTP Content Type (Minify requires one of the constants Minify::TYPE_*)
  34. */
  35. public $contentType = null;
  36. /**
  37. * Create a Minify_Source
  38. *
  39. * In the $spec array(), you can either provide a 'filepath' to an existing
  40. * file (existence will not be checked!) or give 'id' (unique string for
  41. * the content), 'content' (the string content) and 'lastModified'
  42. * (unixtime of last update).
  43. *
  44. * As a shortcut, the controller will replace "//" at the beginning
  45. * of a filepath with $_SERVER['DOCUMENT_ROOT'] . '/'.
  46. *
  47. * @param array $spec options
  48. */
  49. public function __construct($spec)
  50. {
  51. if (isset($spec['filepath'])) {
  52. if (0 === strpos($spec['filepath'], '//')) {
  53. $spec['filepath'] = $_SERVER['DOCUMENT_ROOT'] . substr($spec['filepath'], 1);
  54. }
  55. $segments = explode('.', $spec['filepath']);
  56. $ext = strtolower(array_pop($segments));
  57. switch ($ext) {
  58. case 'js' : $this->contentType = 'application/x-javascript';
  59. break;
  60. case 'css' : $this->contentType = 'text/css';
  61. break;
  62. case 'htm' : // fallthrough
  63. case 'html' : $this->contentType = 'text/html';
  64. break;
  65. }
  66. $this->filepath = $spec['filepath'];
  67. $this->_id = $spec['filepath'];
  68. $this->lastModified = filemtime($spec['filepath'])
  69. // offset for Windows uploaders with out of sync clocks
  70. + round(Minify::$uploaderHoursBehind * 3600);
  71. } elseif (isset($spec['id'])) {
  72. $this->_id = 'id::' . $spec['id'];
  73. if (isset($spec['content'])) {
  74. $this->_content = $spec['content'];
  75. } else {
  76. $this->_getContentFunc = $spec['getContentFunc'];
  77. }
  78. $this->lastModified = isset($spec['lastModified'])
  79. ? $spec['lastModified']
  80. : time();
  81. }
  82. if (isset($spec['contentType'])) {
  83. $this->contentType = $spec['contentType'];
  84. }
  85. if (isset($spec['minifier'])) {
  86. $this->minifier = $spec['minifier'];
  87. }
  88. if (isset($spec['minifyOptions'])) {
  89. $this->minifyOptions = $spec['minifyOptions'];
  90. }
  91. }
  92. /**
  93. * Get content
  94. *
  95. * @return string
  96. */
  97. public function getContent()
  98. {
  99. $content = (null !== $this->filepath)
  100. ? file_get_contents($this->filepath)
  101. : ((null !== $this->_content)
  102. ? $this->_content
  103. : call_user_func($this->_getContentFunc, $this->_id)
  104. );
  105. // remove UTF-8 BOM if present
  106. return (pack("CCC",0xef,0xbb,0xbf) === substr($content, 0, 3))
  107. ? substr($content, 3)
  108. : $content;
  109. }
  110. /**
  111. * Get id
  112. *
  113. * @return string
  114. */
  115. public function getId()
  116. {
  117. return $this->_id;
  118. }
  119. /**
  120. * Verifies a single minification call can handle all sources
  121. *
  122. * @param array $sources Minify_Source instances
  123. *
  124. * @return bool true iff there no sources with specific minifier preferences.
  125. */
  126. public static function haveNoMinifyPrefs($sources)
  127. {
  128. foreach ($sources as $source) {
  129. if (null !== $source->minifier
  130. || null !== $source->minifyOptions) {
  131. return false;
  132. }
  133. }
  134. return true;
  135. }
  136. /**
  137. * Get unique string for a set of sources
  138. *
  139. * @param array $sources Minify_Source instances
  140. *
  141. * @return string
  142. */
  143. public static function getDigest($sources)
  144. {
  145. foreach ($sources as $source) {
  146. $info[] = array(
  147. $source->_id, $source->minifier, $source->minifyOptions
  148. );
  149. }
  150. return md5(serialize($info));
  151. }
  152. /**
  153. * Get content type from a group of sources
  154. *
  155. * This is called if the user doesn't pass in a 'contentType' options
  156. *
  157. * @param array $sources Minify_Source instances
  158. *
  159. * @return string content type. e.g. 'text/css'
  160. */
  161. public static function getContentType($sources)
  162. {
  163. foreach ($sources as $source) {
  164. if ($source->contentType !== null) {
  165. return $source->contentType;
  166. }
  167. }
  168. return 'text/plain';
  169. }
  170. protected $_content = null;
  171. protected $_getContentFunc = null;
  172. protected $_id = null;
  173. }