PageRenderTime 26ms CodeModel.GetById 13ms RepoModel.GetById 1ms app.codeStats 0ms

/vendor/phing/phing/classes/phing/filters/ReplaceTokens.php

https://gitlab.com/Isaki/le331.fr
PHP | 475 lines | 206 code | 56 blank | 213 comment | 28 complexity | a662e17a9fcb7c73b1b303765c8896a4 MD5 | raw file
  1. <?php
  2. /*
  3. * $Id: d83036de1df3622348c9d43dc79147e2af56124b $
  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 $Id: d83036de1df3622348c9d43dc79147e2af56124b $
  44. * @see BaseParamFilterReader
  45. * @package phing.filters
  46. */
  47. class ReplaceTokens extends BaseParamFilterReader implements ChainableReader
  48. {
  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. */
  96. private function replaceTokenCallback($matches)
  97. {
  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(
  125. "Replaced \"" . $this->_beginToken . $key . $this->_endToken . "\" with \"" . $replaceWith . "\"",
  126. Project::MSG_VERBOSE
  127. );
  128. }
  129. return $replaceWith;
  130. }
  131. /**
  132. * Returns stream with tokens having been replaced with appropriate values.
  133. * If a replacement value is not found for a token, the token is left in the stream.
  134. *
  135. * @param null $len
  136. * @return mixed filtered stream, -1 on EOF.
  137. */
  138. public function read($len = null)
  139. {
  140. if (!$this->getInitialized()) {
  141. $this->_initialize();
  142. $this->setInitialized(true);
  143. }
  144. // read from next filter up the chain
  145. $buffer = $this->in->read($len);
  146. if ($buffer === -1) {
  147. return -1;
  148. }
  149. // filter buffer
  150. $buffer = preg_replace_callback(
  151. "/" . preg_quote($this->_beginToken, '/') . "([\w\.\-:]+?)" . preg_quote($this->_endToken, '/') . "/",
  152. array($this, 'replaceTokenCallback'),
  153. $buffer
  154. );
  155. return $buffer;
  156. }
  157. /**
  158. * Sets the "begin token" character.
  159. *
  160. * @param string $beginToken the character used to denote the beginning of a token.
  161. */
  162. public function setBeginToken($beginToken)
  163. {
  164. $this->_beginToken = (string) $beginToken;
  165. }
  166. /**
  167. * Returns the "begin token" character.
  168. *
  169. * @return string The character used to denote the beginning of a token.
  170. */
  171. public function getBeginToken()
  172. {
  173. return $this->_beginToken;
  174. }
  175. /**
  176. * Sets the "end token" character.
  177. *
  178. * @param string $endToken the character used to denote the end of a token
  179. */
  180. public function setEndToken($endToken)
  181. {
  182. $this->_endToken = (string) $endToken;
  183. }
  184. /**
  185. * Returns the "end token" character.
  186. *
  187. * @return the character used to denote the beginning of a token
  188. */
  189. public function getEndToken()
  190. {
  191. return $this->_endToken;
  192. }
  193. /**
  194. * Adds a token element to the map of tokens to replace.
  195. *
  196. * @return object The token added to the map of replacements.
  197. * Must not be <code>null</code>.
  198. */
  199. public function createToken()
  200. {
  201. $num = array_push($this->_tokens, new Token());
  202. return $this->_tokens[$num - 1];
  203. }
  204. /**
  205. * Adds a token source to the sources of this filter.
  206. *
  207. * @return object A Reference to the source just added.
  208. */
  209. public function createTokensource()
  210. {
  211. $num = array_push($this->_tokensources, new TokenSource());
  212. return $this->_tokensources[$num - 1];
  213. }
  214. /**
  215. * Sets the map of tokens to replace.
  216. * ; used by ReplaceTokens::chain()
  217. *
  218. * @param $tokens
  219. * @throws Exception
  220. * @internal param A $array map (String->String) of token keys to replacement
  221. * values. Must not be <code>null</code>.
  222. */
  223. public function setTokens($tokens)
  224. {
  225. // type check, error must never occur, bad code of it does
  226. if (!is_array($tokens)) {
  227. throw new Exception("Excpected 'array', got something else");
  228. }
  229. $this->_tokens = $tokens;
  230. }
  231. /**
  232. * Returns the map of tokens which will be replaced.
  233. * ; used by ReplaceTokens::chain()
  234. *
  235. * @return array A map (String->String) of token keys to replacement values.
  236. */
  237. public function getTokens()
  238. {
  239. return $this->_tokens;
  240. }
  241. /**
  242. * Sets the tokensources to use; used by ReplaceTokens::chain()
  243. *
  244. * @param $sources
  245. * @throws Exception
  246. * @internal param An $array array of token sources.
  247. */
  248. public function setTokensources($sources)
  249. {
  250. // type check
  251. if (!is_array($sources)) {
  252. throw new Exception("Exspected 'array', got something else");
  253. }
  254. $this->_tokensources = $sources;
  255. }
  256. /**
  257. * Returns the token sources used by this filter; used by ReplaceTokens::chain()
  258. *
  259. * @return array
  260. */
  261. public function getTokensources()
  262. {
  263. return $this->_tokensources;
  264. }
  265. /**
  266. * Creates a new ReplaceTokens using the passed in
  267. * Reader for instantiation.
  268. *
  269. * @param Reader $reader
  270. * @throws Exception
  271. * @internal param A $object Reader object providing the underlying stream.
  272. * Must not be <code>null</code>.
  273. *
  274. * @return object A new filter based on this configuration, but filtering
  275. * the specified reader
  276. */
  277. public function chain(Reader $reader)
  278. {
  279. $newFilter = new ReplaceTokens($reader);
  280. $newFilter->setProject($this->getProject());
  281. $newFilter->setBeginToken($this->getBeginToken());
  282. $newFilter->setEndToken($this->getEndToken());
  283. $newFilter->setTokens($this->getTokens());
  284. $newFilter->setTokensources($this->getTokensources());
  285. $newFilter->setInitialized(true);
  286. return $newFilter;
  287. }
  288. /**
  289. * Initializes tokens and loads the replacee-replacer hashtable.
  290. * This method is only called when this filter is used through
  291. * a <filterreader> tag in build file.
  292. */
  293. private function _initialize()
  294. {
  295. $params = $this->getParameters();
  296. if ($params !== null) {
  297. for ($i = 0; $i < count($params); $i++) {
  298. if ($params[$i] !== null) {
  299. $type = $params[$i]->getType();
  300. if ($type === "tokenchar") {
  301. $name = $params[$i]->getName();
  302. if ($name === "begintoken") {
  303. $this->_beginToken = substr($params[$i]->getValue(), 0, 1);
  304. } else {
  305. if ($name === "endtoken") {
  306. $this->_endToken = substr($params[$i]->getValue(), 0, 1);
  307. }
  308. }
  309. } else {
  310. if ($type === "token") {
  311. $name = $params[$i]->getName();
  312. $value = $params[$i]->getValue();
  313. $tok = new Token();
  314. $tok->setKey($name);
  315. $tok->setValue($value);
  316. array_push($this->_tokens, $tok);
  317. } else {
  318. if ($type === "tokensource") {
  319. // Store data from nested tags in local array
  320. $arr = array();
  321. $subparams = $params[$i]->getParams();
  322. foreach ($subparams as $subparam) {
  323. $arr[$subparam->getName()] = $subparam->getValue();
  324. }
  325. // Create TokenSource
  326. $tokensource = new TokenSource();
  327. if (isset($arr["classname"])) {
  328. $tokensource->setClassname($arr["classname"]);
  329. }
  330. // Copy other parameters 1:1 to freshly created TokenSource
  331. foreach ($arr as $key => $value) {
  332. if (strtolower($key) === "classname") {
  333. continue;
  334. }
  335. $param = $tokensource->createParam();
  336. $param->setName($key);
  337. $param->setValue($value);
  338. }
  339. $this->_tokensources[] = $tokensource;
  340. }
  341. }
  342. }
  343. }
  344. }
  345. }
  346. }
  347. }
  348. /**
  349. * Holds a token.
  350. *
  351. * @package phing.filters
  352. */
  353. class Token
  354. {
  355. /**
  356. * Token key.
  357. * @var string
  358. */
  359. private $_key;
  360. /**
  361. * Token value.
  362. * @var string
  363. */
  364. private $_value;
  365. /**
  366. * Sets the token key.
  367. *
  368. * @param string $key The key for this token. Must not be <code>null</code>.
  369. */
  370. public function setKey($key)
  371. {
  372. $this->_key = (string) $key;
  373. }
  374. /**
  375. * Sets the token value.
  376. *
  377. * @param string $value The value for this token. Must not be <code>null</code>.
  378. */
  379. public function setValue($value)
  380. {
  381. // special case for boolean values
  382. if (is_bool($value)) {
  383. if ($value) {
  384. $this->_value = "true";
  385. } else {
  386. $this->_value = "false";
  387. }
  388. } else {
  389. $this->_value = (string) $value;
  390. }
  391. }
  392. /**
  393. * Returns the key for this token.
  394. *
  395. * @return string The key for this token.
  396. */
  397. public function getKey()
  398. {
  399. return $this->_key;
  400. }
  401. /**
  402. * Returns the value for this token.
  403. *
  404. * @return string The value for this token.
  405. */
  406. public function getValue()
  407. {
  408. return $this->_value;
  409. }
  410. /**
  411. * Sets the token value from text.
  412. *
  413. * @param string $value The value for this token. Must not be <code>null</code>.
  414. */
  415. public function addText($value)
  416. {
  417. $this->setValue($value);
  418. }
  419. }