PageRenderTime 51ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/install/phing/classes/phing/filters/ReplaceTokens.php

https://github.com/chregu/fluxcms
PHP | 415 lines | 162 code | 53 blank | 200 comment | 25 complexity | d4a6bed45e40b241b2c13c6155964284 MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause, Apache-2.0, LGPL-2.1
  1. <?php
  2. /*
  3. * $Id$
  4. *
  5. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  6. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  7. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  8. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  9. * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  10. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  11. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  12. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  13. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  14. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  15. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  16. *
  17. * This software consists of voluntary contributions made by many individuals
  18. * and is licensed under the LGPL. For more information please see
  19. * <http://phing.info>.
  20. */
  21. include_once 'phing/filters/BaseParamFilterReader.php';
  22. include_once 'phing/types/TokenSource.php';
  23. include_once 'phing/filters/ChainableReader.php';
  24. /*
  25. * Replaces tokens in the original input with user-supplied values.
  26. *
  27. * Example:
  28. *
  29. * <pre><replacetokens begintoken="#" endtoken="#">;
  30. * <token key="DATE" value="${TODAY}"/>
  31. * </replacetokens></pre>
  32. *
  33. * Or:
  34. *
  35. * <pre><filterreader classname="phing.filters.ReplaceTokens">
  36. * <param type="tokenchar" name="begintoken" value="#"/>
  37. * <param type="tokenchar" name="endtoken" value="#"/>
  38. * <param type="token" name="DATE" value="${TODAY}"/>
  39. * </filterreader></pre>
  40. *
  41. * @author <a href="mailto:yl@seasonfive.com">Yannick Lecaillez</a>
  42. * @author hans lellelid, hans@velum.net
  43. * @version $Revision: 1.13 $ $Date: 2005/02/27 20:52:08 $
  44. * @access public
  45. * @see BaseParamFilterReader
  46. * @package phing.filters
  47. */
  48. class ReplaceTokens extends BaseParamFilterReader implements ChainableReader {
  49. /**
  50. * Default "begin token" character.
  51. * @var string
  52. */
  53. const DEFAULT_BEGIN_TOKEN = "@";
  54. /**
  55. * Default "end token" character.
  56. * @var string
  57. */
  58. const DEFAULT_END_TOKEN = "@";
  59. /**
  60. * [Deprecated] Data that must be read from, if not null.
  61. * @var string
  62. */
  63. private $_queuedData = null;
  64. /**
  65. * Array to hold the replacee-replacer pairs (String to String).
  66. * @var array
  67. */
  68. private $_tokens = array();
  69. /**
  70. * Array to hold the token sources that make tokens from
  71. * different sources available
  72. * @var array
  73. */
  74. private $_tokensources = array();
  75. /**
  76. * Array holding all tokens given directly to the Filter and
  77. * those passed via a TokenSource.
  78. * @var array
  79. */
  80. private $_alltokens = null;
  81. /**
  82. * Character marking the beginning of a token.
  83. * @var string
  84. */
  85. private $_beginToken = "@"; // self::DEFAULT_BEGIN_TOKEN;
  86. /**
  87. * Character marking the end of a token.
  88. * @var string
  89. */
  90. private $_endToken = "@"; //self::DEFAULT_END_TOKEN;
  91. /**
  92. * Performs lookup on key and returns appropriate replacement string.
  93. * @param array $matches Array of 1 el containing key to search for.
  94. * @return string Text with which to replace key or value of key if none is found.
  95. * @access private
  96. */
  97. private function replaceTokenCallback($matches) {
  98. $key = $matches[1];
  99. /* Get tokens from tokensource and merge them with the
  100. * tokens given directly via build file. This should be
  101. * done a bit more elegantly
  102. */
  103. if ($this->_alltokens === null) {
  104. $this->_alltokens = array();
  105. $count = count($this->_tokensources);
  106. for ($i = 0; $i < $count; $i++) {
  107. $source = $this->_tokensources[$i];
  108. $this->_alltokens = array_merge($this->_alltokens, $source->getTokens());
  109. }
  110. $this->_alltokens = array_merge($this->_tokens, $this->_alltokens);
  111. }
  112. $tokens = $this->_alltokens;
  113. $replaceWith = null;
  114. $count = count($tokens);
  115. for ($i = 0; $i < $count; $i++) {
  116. if ($tokens[$i]->getKey() === $key) {
  117. $replaceWith = $tokens[$i]->getValue();
  118. }
  119. }
  120. if ($replaceWith === null) {
  121. $replaceWith = $this->_beginToken . $key . $this->_endToken;
  122. $this->log("No token defined for key \"".$this->_beginToken . $key . $this->_endToken."\"");
  123. } else {
  124. $this->log("Replaced \"".$this->_beginToken . $key . $this->_endToken ."\" with \"".$replaceWith."\"");
  125. }
  126. return $replaceWith;
  127. }
  128. /**
  129. * Returns stream with tokens having been replaced with appropriate values.
  130. * If a replacement value is not found for a token, the token is left in the stream.
  131. *
  132. * @return mixed filtered stream, -1 on EOF.
  133. */
  134. function read($len = null) {
  135. if ( !$this->getInitialized() ) {
  136. $this->_initialize();
  137. $this->setInitialized(true);
  138. }
  139. // read from next filter up the chain
  140. $buffer = $this->in->read($len);
  141. if($buffer === -1) {
  142. return -1;
  143. }
  144. // filter buffer
  145. $buffer = preg_replace_callback(
  146. "/".preg_quote($this->_beginToken)."([\w\.\-]+?)".preg_quote($this->_endToken)."/",
  147. array($this, 'replaceTokenCallback'), $buffer);
  148. return $buffer;
  149. }
  150. /**
  151. * Sets the "begin token" character.
  152. *
  153. * @param string $beginToken the character used to denote the beginning of a token.
  154. */
  155. function setBeginToken($beginToken) {
  156. $this->_beginToken = (string) $beginToken;
  157. }
  158. /**
  159. * Returns the "begin token" character.
  160. *
  161. * @return string The character used to denote the beginning of a token.
  162. */
  163. function getBeginToken() {
  164. return $this->_beginToken;
  165. }
  166. /**
  167. * Sets the "end token" character.
  168. *
  169. * @param string $endToken the character used to denote the end of a token
  170. */
  171. function setEndToken($endToken) {
  172. $this->_endToken = (string) $endToken;
  173. }
  174. /**
  175. * Returns the "end token" character.
  176. *
  177. * @return the character used to denote the beginning of a token
  178. */
  179. function getEndToken() {
  180. return $this->_endToken;
  181. }
  182. /**
  183. * Adds a token element to the map of tokens to replace.
  184. *
  185. * @return object The token added to the map of replacements.
  186. * Must not be <code>null</code>.
  187. */
  188. function createToken() {
  189. $num = array_push($this->_tokens, new Token());
  190. return $this->_tokens[$num-1];
  191. }
  192. /**
  193. * Adds a token source to the sources of this filter.
  194. *
  195. * @return object A Reference to the source just added.
  196. */
  197. function createTokensource() {
  198. $num = array_push($this->_tokensources, new TokenSource());
  199. return $this->_tokensources[$num-1];
  200. }
  201. /**
  202. * Sets the map of tokens to replace.
  203. * ; used by ReplaceTokens::chain()
  204. *
  205. * @param array A map (String->String) of token keys to replacement
  206. * values. Must not be <code>null</code>.
  207. */
  208. function setTokens($tokens) {
  209. // type check, error must never occur, bad code of it does
  210. if ( !is_array($tokens) ) {
  211. throw new Exception("Excpected 'array', got something else");
  212. }
  213. $this->_tokens = $tokens;
  214. }
  215. /**
  216. * Returns the map of tokens which will be replaced.
  217. * ; used by ReplaceTokens::chain()
  218. *
  219. * @return array A map (String->String) of token keys to replacement values.
  220. */
  221. function getTokens() {
  222. return $this->_tokens;
  223. }
  224. /**
  225. * Sets the tokensources to use; used by ReplaceTokens::chain()
  226. *
  227. * @param array An array of token sources.
  228. */
  229. function setTokensources($sources) {
  230. // type check
  231. if ( !is_array($sources)) {
  232. throw new Exception("Exspected 'array', got something else");
  233. }
  234. $this->_tokensources = $sources;
  235. }
  236. /**
  237. * Returns the token sources used by this filter; used by ReplaceTokens::chain()
  238. *
  239. * @return array
  240. */
  241. function getTokensources() {
  242. return $this->_tokensources;
  243. }
  244. /**
  245. * Creates a new ReplaceTokens using the passed in
  246. * Reader for instantiation.
  247. *
  248. * @param object A Reader object providing the underlying stream.
  249. * Must not be <code>null</code>.
  250. *
  251. * @return object A new filter based on this configuration, but filtering
  252. * the specified reader
  253. */
  254. function chain(Reader $reader) {
  255. $newFilter = new ReplaceTokens($reader);
  256. $newFilter->setProject($this->getProject());
  257. $newFilter->setBeginToken($this->getBeginToken());
  258. $newFilter->setEndToken($this->getEndToken());
  259. $newFilter->setTokens($this->getTokens());
  260. $newFilter->setTokensources($this->getTokensources());
  261. $newFilter->setInitialized(true);
  262. return $newFilter;
  263. }
  264. /**
  265. * Initializes tokens and loads the replacee-replacer hashtable.
  266. * This method is only called when this filter is used through
  267. * a <filterreader> tag in build file.
  268. */
  269. private function _initialize() {
  270. $params = $this->getParameters();
  271. if ( $params !== null ) {
  272. for($i = 0 ; $i<count($params) ; $i++) {
  273. if ( $params[$i] !== null ) {
  274. $type = $params[$i]->getType();
  275. if ( $type === "tokenchar" ) {
  276. $name = $params[$i]->getName();
  277. if ( $name === "begintoken" ) {
  278. $this->_beginToken = substr($params[$i]->getValue(), 0, 1);
  279. } else if ( $name === "endtoken" ) {
  280. $this->_endToken = substr($params[$i]->getValue(), 0, 1);
  281. }
  282. } else if ( $type === "token" ) {
  283. $name = $params[$i]->getName();
  284. $value = $params[$i]->getValue();
  285. $tok = new Token();
  286. $tok->setKey($name);
  287. $tok->setValue($value);
  288. array_push($this->_tokens, $tok);
  289. } else if ( $type === "tokensource" ) {
  290. // Store data from nested tags in local array
  291. $arr = array(); $subparams = $params[$i]->getParams();
  292. $count = count($subparams);
  293. for ($i = 0; $i < $count; $i++) {
  294. $arr[$subparams[$i]->getName()] = $subparams[$i]->getValue();
  295. }
  296. // Create TokenSource
  297. $tokensource = new TokenSource();
  298. if (isset($arr["classname"]))
  299. $tokensource->setClassname($arr["classname"]);
  300. // Copy other parameters 1:1 to freshly created TokenSource
  301. foreach ($arr as $key => $value) {
  302. if (strtolower($key) === "classname")
  303. continue;
  304. $param = $tokensource->createParam();
  305. $param->setName($key);
  306. $param->setValue($value);
  307. }
  308. $this->_tokensources[] = $tokensource;
  309. }
  310. }
  311. }
  312. }
  313. }
  314. }
  315. /**
  316. * Holds a token.
  317. */
  318. class Token {
  319. /**
  320. * Token key.
  321. * @var string
  322. */
  323. private $_key;
  324. /**
  325. * Token value.
  326. * @var string
  327. */
  328. private $_value;
  329. /**
  330. * Sets the token key.
  331. *
  332. * @param string $key The key for this token. Must not be <code>null</code>.
  333. */
  334. function setKey($key) {
  335. $this->_key = (string) $key;
  336. }
  337. /**
  338. * Sets the token value.
  339. *
  340. * @param string $value The value for this token. Must not be <code>null</code>.
  341. */
  342. function setValue($value) {
  343. $this->_value = (string) $value;
  344. }
  345. /**
  346. * Returns the key for this token.
  347. *
  348. * @return string The key for this token.
  349. */
  350. function getKey() {
  351. return $this->_key;
  352. }
  353. /**
  354. * Returns the value for this token.
  355. *
  356. * @return string The value for this token.
  357. */
  358. function getValue() {
  359. return $this->_value;
  360. }
  361. }
  362. ?>