/core/model/modx/modscript.class.php

https://github.com/hatone/revolution · PHP · 174 lines · 114 code · 8 blank · 52 comment · 29 complexity · b5875a3281ffed7b8acfa086cc7c35eb MD5 · raw file

  1. <?php
  2. /**
  3. * @package modx
  4. */
  5. /**
  6. * An element representing executable PHP script content.
  7. *
  8. * {@inheritdoc}
  9. *
  10. * @property int $id
  11. * @property string $name The name of the script
  12. * @property string $description The description of the script
  13. * @property int $editor_type Deprecated
  14. * @property int $category The Category this Script resides in
  15. * @abstract Implement a derivative class that defines a table for storage.
  16. * @package modx
  17. */
  18. class modScript extends modElement {
  19. /**
  20. * The name of the script
  21. * @var string $_scriptName
  22. */
  23. public $_scriptName= null;
  24. /**
  25. * The cache key of the script
  26. * @var string $_scriptCacheKey
  27. */
  28. public $_scriptCacheKey= null;
  29. /**
  30. * Override set to properly strip invalid tags from script code
  31. *
  32. * {@inheritdoc}
  33. */
  34. public function set($k, $v= null, $vType= '') {
  35. if (in_array($k, array('snippet', 'plugincode', 'content'))) {
  36. $v= trim($v);
  37. if (strncmp($v, '<?', 2) == 0) {
  38. $v= substr($v, 2);
  39. if (strncmp($v, 'php', 3) == 0) $v= substr($v, 3);
  40. }
  41. if (substr($v, -2, 2) == '?>') $v= substr($v, 0, -2);
  42. $v= trim($v, " \n\r\0\x0B");
  43. }
  44. $set= parent::set($k, $v, $vType);
  45. return $set;
  46. }
  47. /**
  48. * Process specifically script-related functionality for modScript objects.
  49. *
  50. * {@inheritdoc}
  51. */
  52. public function process($properties= null, $content= null) {
  53. parent :: process($properties, $content);
  54. if (!$this->_processed) {
  55. $scriptName= $this->getScriptName();
  56. $this->_result= function_exists($scriptName);
  57. if (!$this->_result) {
  58. $this->_result= $this->loadScript();
  59. }
  60. if ($this->_result) {
  61. $this->xpdo->event->params= $this->_properties; /* store params inside event object */
  62. ob_start();
  63. $this->_output= $scriptName($this->_properties);
  64. $this->_output= ob_get_contents() . $this->_output;
  65. ob_end_clean();
  66. if ($this->_output && is_string($this->_output)) {
  67. /* collect element tags in the evaluated content and process them */
  68. $maxIterations= intval($this->xpdo->getOption('parser_max_iterations',null,10));
  69. $this->xpdo->parser->processElementTags(
  70. $this->_tag,
  71. $this->_output,
  72. $this->xpdo->parser->isProcessingUncacheable(),
  73. $this->xpdo->parser->isRemovingUnprocessed(),
  74. '[[',
  75. ']]',
  76. array(),
  77. $maxIterations
  78. );
  79. }
  80. $this->filterOutput();
  81. unset ($this->xpdo->event->params);
  82. $this->cache();
  83. }
  84. }
  85. $this->_processed= true;
  86. /* finally, return the processed element content */
  87. return $this->_output;
  88. }
  89. /**
  90. * Get the name of the script source file, written to the cache file system
  91. *
  92. * @return string The filename containing the function generated from the
  93. * script element.
  94. */
  95. public function getScriptCacheKey() {
  96. if ($this->_scriptCacheKey === null) {
  97. $this->_scriptCacheKey= str_replace('_', '/', $this->getScriptName());
  98. }
  99. return $this->_scriptCacheKey;
  100. }
  101. /**
  102. * Get the name of the function the script has been given.
  103. *
  104. * @return string The function name representing this script element.
  105. */
  106. public function getScriptName() {
  107. if ($this->_scriptName === null) {
  108. $className= $this->_class;
  109. $this->_scriptName= 'elements_' . strtolower($className) . '_' . $this->get('id');
  110. }
  111. return $this->_scriptName;
  112. }
  113. /**
  114. * Loads and evaluates the script, returning the result.
  115. *
  116. * @return boolean True if the result of the script is not false.
  117. */
  118. public function loadScript() {
  119. $includeFilename = $this->xpdo->getCachePath() . 'includes/' . $this->getScriptCacheKey() . '.include.cache.php';
  120. $result = file_exists($includeFilename);
  121. $outdated = false;
  122. if ($result && $this->isStatic()) {
  123. $includeMTime = filemtime($includeFilename);
  124. $sourceMTime = filemtime($this->getSourceFile());
  125. $outdated = $sourceMTime > $includeMTime;
  126. }
  127. if (!$result || $outdated) {
  128. $script= false;
  129. if (!$outdated) {
  130. $script= $this->xpdo->cacheManager->get($this->getScriptCacheKey(), array(
  131. xPDO::OPT_CACHE_KEY => $this->xpdo->getOption('cache_scripts_key', null, 'scripts'),
  132. xPDO::OPT_CACHE_HANDLER => $this->xpdo->getOption('cache_scripts_handler', null, $this->xpdo->getOption(xPDO::OPT_CACHE_HANDLER)),
  133. xPDO::OPT_CACHE_FORMAT => (integer) $this->xpdo->getOption('cache_scripts_format', null, $this->xpdo->getOption(xPDO::OPT_CACHE_FORMAT, null, xPDOCacheManager::CACHE_PHP)),
  134. ));
  135. }
  136. if (!$script) {
  137. $script= $this->xpdo->cacheManager->generateScript($this);
  138. }
  139. if (!empty($script)) {
  140. $result = $this->xpdo->cacheManager->writeFile($includeFilename, "<?php\n" . $script);
  141. }
  142. }
  143. if ($result) {
  144. $result = include($includeFilename);
  145. if ($result) {
  146. $result = function_exists($this->getScriptName());
  147. }
  148. }
  149. return ($result !== false);
  150. }
  151. public function getFileContent(array $options = array()) {
  152. $content = parent::getFileContent($options);
  153. $content= trim($content);
  154. if (strncmp($content, '<?', 2) == 0) {
  155. $content= substr($content, 2);
  156. if (strncmp($content, 'php', 3) == 0) $content= substr($content, 3);
  157. }
  158. if (substr($content, -2, 2) == '?>') $content= substr($content, 0, -2);
  159. $content= trim($content, " \n\r\0\x0B");
  160. return $content;
  161. }
  162. public function setFileContent($content, array $options = array()) {
  163. $content = "<?php\n{$content}";
  164. return parent::setFileContent($content, $options);
  165. }
  166. }