/core/model/modx/modstaticresource.class.php

https://github.com/gbds/revolution · PHP · 201 lines · 136 code · 8 blank · 57 comment · 31 complexity · b17d73150ccd7f25f14a1e638764f28c MD5 · raw file

  1. <?php
  2. /**
  3. * A derivative of modResource that stores content on the filesystem.
  4. *
  5. * {@inheritdoc}
  6. *
  7. * @package modx
  8. */
  9. class modStaticResource extends modResource {
  10. /**
  11. * @var string Path of the file containing the source content, relative to
  12. * the {@link modStaticResource::$_sourcePath}.
  13. */
  14. protected $_sourceFile= '';
  15. /**
  16. * @var integer Size of the source file content in bytes.
  17. */
  18. protected $_sourceFileSize= 0;
  19. /**
  20. * @var string An absolute base filesystem path where the source file
  21. * exists.
  22. */
  23. protected $_sourcePath= '';
  24. function __construct(& $xpdo) {
  25. parent :: __construct($xpdo);
  26. $this->set('class_key','modStaticResource');
  27. }
  28. /**
  29. * Get the absolute path to the static source file represented by this instance.
  30. *
  31. * @param array $options An array of options.
  32. * @return string The absolute path to the static source file.
  33. */
  34. public function getSourceFile(array $options = array()) {
  35. if (empty($this->_sourceFile)) {
  36. $filename = parent :: getContent($options);
  37. if (!empty($filename)) {
  38. $array = array();
  39. if ($this->xpdo->getParser() && $this->xpdo->parser->collectElementTags($filename, $array)) {
  40. $this->xpdo->parser->processElementTags('', $filename);
  41. }
  42. }
  43. if (!file_exists($filename)) {
  44. $this->_sourcePath= $this->xpdo->getOption('resource_static_path', $options, $this->xpdo->getOption('base_path'));
  45. if ($this->xpdo->getParser() && $this->xpdo->parser->collectElementTags($this->_sourcePath, $array)) {
  46. $this->xpdo->parser->processElementTags('', $this->_sourcePath);
  47. }
  48. $this->_sourceFile= $this->_sourcePath . $filename;
  49. } else {
  50. $this->_sourceFile= $filename;
  51. }
  52. }
  53. return $this->_sourceFile;
  54. }
  55. /**
  56. * Get the filesize of the static source file represented by this instance.
  57. *
  58. * @param array $options An array of options.
  59. * @return integer The filesize of the source file in bytes.
  60. */
  61. public function getSourceFileSize(array $options = array()) {
  62. if (empty($this->_sourceFileSize)) {
  63. $this->getSourceFile($options);
  64. if (file_exists($this->_sourceFile)) {
  65. $this->_sourceFileSize = filesize($this->_sourceFile);
  66. }
  67. }
  68. return $this->_sourceFileSize;
  69. }
  70. /**
  71. * Treats the local content as a filename to load the raw content from.
  72. *
  73. * {@inheritdoc}
  74. */
  75. public function getContent(array $options = array()) {
  76. $content = '';
  77. $this->getSourceFile($options);
  78. if (!empty ($this->_sourceFile)) {
  79. if (file_exists($this->_sourceFile)) {
  80. $content= $this->getFileContent($this->_sourceFile);
  81. if ($content === false) {
  82. $content = '';
  83. $this->xpdo->log(xPDO::LOG_LEVEL_ERROR, "No content could be retrieved from source file: {$this->_sourceFile}");
  84. }
  85. } else {
  86. $this->xpdo->log(xPDO::LOG_LEVEL_ERROR, "Could not locate source file: {$this->_sourceFile}");
  87. }
  88. } else {
  89. $this->xpdo->log(xPDO::LOG_LEVEL_ERROR, "No source file specified.");
  90. }
  91. return $content;
  92. }
  93. /**
  94. * Retrieve the resource content stored in a physical file.
  95. *
  96. * @access public
  97. * @param string $file A path to the file representing the resource content.
  98. * @return string The content of the file, of false if it could not be
  99. * retrieved.
  100. */
  101. public function getFileContent($file, array $options = array()) {
  102. $content= false;
  103. $memory_limit= ini_get('memory_limit');
  104. if (!$memory_limit) $memory_limit= '8M';
  105. $byte_limit= $this->_bytes($memory_limit) * .5;
  106. $filesize= $this->getSourceFileSize($options);
  107. if ($this->getOne('ContentType')) {
  108. $type= $this->ContentType->get('mime_type') ? $this->ContentType->get('mime_type') : 'text/html';
  109. if ($this->ContentType->get('binary') || $filesize > $byte_limit) {
  110. if ($alias= array_search($this->xpdo->resourceIdentifier, $this->xpdo->aliasMap)) {
  111. $name= basename($alias);
  112. } elseif ($this->get('alias')) {
  113. $name= $this->get('alias');
  114. if ($ext= $this->ContentType->getExtension()) {
  115. $name .= ".{$ext}";
  116. }
  117. } elseif ($name= $this->get('pagetitle')) {
  118. $name= $this->cleanAlias($name);
  119. if ($ext= $this->ContentType->getExtension()) {
  120. $name .= ".{$ext}";
  121. }
  122. } else {
  123. $name= 'download';
  124. if ($ext= $this->ContentType->getExtension()) {
  125. $name .= ".{$ext}";
  126. }
  127. }
  128. $header= 'Content-Type: ' . $type;
  129. if (!$this->ContentType->get('binary')) {
  130. $charset= $this->xpdo->getOption('modx_charset',null,'UTF-8');
  131. $header .= '; charset=' . $charset;
  132. }
  133. header($header);
  134. if ($this->ContentType->get('binary')) {
  135. header('Content-Transfer-Encoding: binary');
  136. }
  137. if ($filesize > 0) {
  138. $header= 'Content-Length: ' . $filesize;
  139. header($header);
  140. }
  141. $header= 'Cache-Control: public';
  142. header($header);
  143. $header= 'Content-Disposition: ' . ($this->get('content_dispo') ? 'attachment; filename=' . $name : 'inline');
  144. header($header);
  145. $header= 'Vary: User-Agent';
  146. header($header);
  147. if ($customHeaders= $this->ContentType->get('headers')) {
  148. foreach ($customHeaders as $headerKey => $headerString) {
  149. header($headerString);
  150. }
  151. }
  152. @session_write_close();
  153. while (@ob_end_clean()) {}
  154. readfile($file);
  155. die();
  156. }
  157. else {
  158. $content = file_get_contents($file);
  159. }
  160. if (!is_string($content)) {
  161. $this->xpdo->log(xPDO::LOG_LEVEL_ERROR, "modStaticResource->getFileContent({$file}): Could not get content from file.");
  162. }
  163. }
  164. return $content;
  165. }
  166. /**
  167. * Converts to bytes from PHP ini_get() format.
  168. *
  169. * PHP ini modifiers for byte values:
  170. * <ul>
  171. * <li>G = gigabytes</li>
  172. * <li>M = megabytes</li>
  173. * <li>K = kilobytes</li>
  174. * </ul>
  175. *
  176. * @access protected
  177. * @param string $value Number of bytes represented in PHP ini value format.
  178. * @return integer The value converted to bytes.
  179. */
  180. protected function _bytes($value) {
  181. $value = trim($value);
  182. $modifier = strtolower($value{strlen($value)-1});
  183. switch($modifier) {
  184. case 'g':
  185. $value *= 1024;
  186. case 'm':
  187. $value *= 1024;
  188. case 'k':
  189. $value *= 1024;
  190. }
  191. return $value;
  192. }
  193. }