Mercurial > hg > isophonics-drupal-site
comparison vendor/squizlabs/php_codesniffer/src/Fixer.php @ 17:129ea1e6d783
Update, including to Drupal core 8.6.10
author | Chris Cannam |
---|---|
date | Thu, 28 Feb 2019 13:21:36 +0000 |
parents | |
children | af1871eacc83 |
comparison
equal
deleted
inserted
replaced
16:c2387f117808 | 17:129ea1e6d783 |
---|---|
1 <?php | |
2 /** | |
3 * A helper class for fixing errors. | |
4 * | |
5 * Provides helper functions that act upon a token array and modify the file | |
6 * content. | |
7 * | |
8 * @author Greg Sherwood <gsherwood@squiz.net> | |
9 * @copyright 2006-2015 Squiz Pty Ltd (ABN 77 084 670 600) | |
10 * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence | |
11 */ | |
12 | |
13 namespace PHP_CodeSniffer; | |
14 | |
15 use PHP_CodeSniffer\Files\File; | |
16 use PHP_CodeSniffer\Util\Common; | |
17 | |
18 class Fixer | |
19 { | |
20 | |
21 /** | |
22 * Is the fixer enabled and fixing a file? | |
23 * | |
24 * Sniffs should check this value to ensure they are not | |
25 * doing extra processing to prepare for a fix when fixing is | |
26 * not required. | |
27 * | |
28 * @var boolean | |
29 */ | |
30 public $enabled = false; | |
31 | |
32 /** | |
33 * The number of times we have looped over a file. | |
34 * | |
35 * @var integer | |
36 */ | |
37 public $loops = 0; | |
38 | |
39 /** | |
40 * The file being fixed. | |
41 * | |
42 * @var \PHP_CodeSniffer\Files\File | |
43 */ | |
44 private $currentFile = null; | |
45 | |
46 /** | |
47 * The list of tokens that make up the file contents. | |
48 * | |
49 * This is a simplified list which just contains the token content and nothing | |
50 * else. This is the array that is updated as fixes are made, not the file's | |
51 * token array. Imploding this array will give you the file content back. | |
52 * | |
53 * @var array<int, string> | |
54 */ | |
55 private $tokens = []; | |
56 | |
57 /** | |
58 * A list of tokens that have already been fixed. | |
59 * | |
60 * We don't allow the same token to be fixed more than once each time | |
61 * through a file as this can easily cause conflicts between sniffs. | |
62 * | |
63 * @var int[] | |
64 */ | |
65 private $fixedTokens = []; | |
66 | |
67 /** | |
68 * The last value of each fixed token. | |
69 * | |
70 * If a token is being "fixed" back to its last value, the fix is | |
71 * probably conflicting with another. | |
72 * | |
73 * @var array<int, string> | |
74 */ | |
75 private $oldTokenValues = []; | |
76 | |
77 /** | |
78 * A list of tokens that have been fixed during a changeset. | |
79 * | |
80 * All changes in changeset must be able to be applied, or else | |
81 * the entire changeset is rejected. | |
82 * | |
83 * @var array | |
84 */ | |
85 private $changeset = []; | |
86 | |
87 /** | |
88 * Is there an open changeset. | |
89 * | |
90 * @var boolean | |
91 */ | |
92 private $inChangeset = false; | |
93 | |
94 /** | |
95 * Is the current fixing loop in conflict? | |
96 * | |
97 * @var boolean | |
98 */ | |
99 private $inConflict = false; | |
100 | |
101 /** | |
102 * The number of fixes that have been performed. | |
103 * | |
104 * @var integer | |
105 */ | |
106 private $numFixes = 0; | |
107 | |
108 | |
109 /** | |
110 * Starts fixing a new file. | |
111 * | |
112 * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being fixed. | |
113 * | |
114 * @return void | |
115 */ | |
116 public function startFile(File $phpcsFile) | |
117 { | |
118 $this->currentFile = $phpcsFile; | |
119 $this->numFixes = 0; | |
120 $this->fixedTokens = []; | |
121 | |
122 $tokens = $phpcsFile->getTokens(); | |
123 $this->tokens = []; | |
124 foreach ($tokens as $index => $token) { | |
125 if (isset($token['orig_content']) === true) { | |
126 $this->tokens[$index] = $token['orig_content']; | |
127 } else { | |
128 $this->tokens[$index] = $token['content']; | |
129 } | |
130 } | |
131 | |
132 }//end startFile() | |
133 | |
134 | |
135 /** | |
136 * Attempt to fix the file by processing it until no fixes are made. | |
137 * | |
138 * @return boolean | |
139 */ | |
140 public function fixFile() | |
141 { | |
142 $fixable = $this->currentFile->getFixableCount(); | |
143 if ($fixable === 0) { | |
144 // Nothing to fix. | |
145 return false; | |
146 } | |
147 | |
148 $this->enabled = true; | |
149 | |
150 $this->loops = 0; | |
151 while ($this->loops < 50) { | |
152 ob_start(); | |
153 | |
154 // Only needed once file content has changed. | |
155 $contents = $this->getContents(); | |
156 | |
157 if (PHP_CODESNIFFER_VERBOSITY > 2) { | |
158 @ob_end_clean(); | |
159 echo '---START FILE CONTENT---'.PHP_EOL; | |
160 $lines = explode($this->currentFile->eolChar, $contents); | |
161 $max = strlen(count($lines)); | |
162 foreach ($lines as $lineNum => $line) { | |
163 $lineNum++; | |
164 echo str_pad($lineNum, $max, ' ', STR_PAD_LEFT).'|'.$line.PHP_EOL; | |
165 } | |
166 | |
167 echo '--- END FILE CONTENT ---'.PHP_EOL; | |
168 ob_start(); | |
169 } | |
170 | |
171 $this->inConflict = false; | |
172 $this->currentFile->ruleset->populateTokenListeners(); | |
173 $this->currentFile->setContent($contents); | |
174 $this->currentFile->process(); | |
175 ob_end_clean(); | |
176 | |
177 $this->loops++; | |
178 | |
179 if (PHP_CODESNIFFER_CBF === true && PHP_CODESNIFFER_VERBOSITY > 0) { | |
180 echo "\r".str_repeat(' ', 80)."\r"; | |
181 echo "\t=> Fixing file: $this->numFixes/$fixable violations remaining [made $this->loops pass"; | |
182 if ($this->loops > 1) { | |
183 echo 'es'; | |
184 } | |
185 | |
186 echo ']... '; | |
187 } | |
188 | |
189 if ($this->numFixes === 0 && $this->inConflict === false) { | |
190 // Nothing left to do. | |
191 break; | |
192 } else if (PHP_CODESNIFFER_VERBOSITY > 1) { | |
193 echo "\t* fixed $this->numFixes violations, starting loop ".($this->loops + 1).' *'.PHP_EOL; | |
194 } | |
195 }//end while | |
196 | |
197 $this->enabled = false; | |
198 | |
199 if ($this->numFixes > 0) { | |
200 if (PHP_CODESNIFFER_VERBOSITY > 1) { | |
201 if (ob_get_level() > 0) { | |
202 ob_end_clean(); | |
203 } | |
204 | |
205 echo "\t*** Reached maximum number of loops with $this->numFixes violations left unfixed ***".PHP_EOL; | |
206 ob_start(); | |
207 } | |
208 | |
209 return false; | |
210 } | |
211 | |
212 return true; | |
213 | |
214 }//end fixFile() | |
215 | |
216 | |
217 /** | |
218 * Generates a text diff of the original file and the new content. | |
219 * | |
220 * @param string $filePath Optional file path to diff the file against. | |
221 * If not specified, the original version of the | |
222 * file will be used. | |
223 * @param boolean $colors Print colored output or not. | |
224 * | |
225 * @return string | |
226 */ | |
227 public function generateDiff($filePath=null, $colors=true) | |
228 { | |
229 if ($filePath === null) { | |
230 $filePath = $this->currentFile->getFilename(); | |
231 } | |
232 | |
233 $cwd = getcwd().DIRECTORY_SEPARATOR; | |
234 if (strpos($filePath, $cwd) === 0) { | |
235 $filename = substr($filePath, strlen($cwd)); | |
236 } else { | |
237 $filename = $filePath; | |
238 } | |
239 | |
240 $contents = $this->getContents(); | |
241 | |
242 $tempName = tempnam(sys_get_temp_dir(), 'phpcs-fixer'); | |
243 $fixedFile = fopen($tempName, 'w'); | |
244 fwrite($fixedFile, $contents); | |
245 | |
246 // We must use something like shell_exec() because whitespace at the end | |
247 // of lines is critical to diff files. | |
248 $filename = escapeshellarg($filename); | |
249 $cmd = "diff -u -L$filename -LPHP_CodeSniffer $filename \"$tempName\""; | |
250 | |
251 $diff = shell_exec($cmd); | |
252 | |
253 fclose($fixedFile); | |
254 if (is_file($tempName) === true) { | |
255 unlink($tempName); | |
256 } | |
257 | |
258 if ($colors === false) { | |
259 return $diff; | |
260 } | |
261 | |
262 $diffLines = explode(PHP_EOL, $diff); | |
263 if (count($diffLines) === 1) { | |
264 // Seems to be required for cygwin. | |
265 $diffLines = explode("\n", $diff); | |
266 } | |
267 | |
268 $diff = []; | |
269 foreach ($diffLines as $line) { | |
270 if (isset($line[0]) === true) { | |
271 switch ($line[0]) { | |
272 case '-': | |
273 $diff[] = "\033[31m$line\033[0m"; | |
274 break; | |
275 case '+': | |
276 $diff[] = "\033[32m$line\033[0m"; | |
277 break; | |
278 default: | |
279 $diff[] = $line; | |
280 } | |
281 } | |
282 } | |
283 | |
284 $diff = implode(PHP_EOL, $diff); | |
285 | |
286 return $diff; | |
287 | |
288 }//end generateDiff() | |
289 | |
290 | |
291 /** | |
292 * Get a count of fixes that have been performed on the file. | |
293 * | |
294 * This value is reset every time a new file is started, or an existing | |
295 * file is restarted. | |
296 * | |
297 * @return int | |
298 */ | |
299 public function getFixCount() | |
300 { | |
301 return $this->numFixes; | |
302 | |
303 }//end getFixCount() | |
304 | |
305 | |
306 /** | |
307 * Get the current content of the file, as a string. | |
308 * | |
309 * @return string | |
310 */ | |
311 public function getContents() | |
312 { | |
313 $contents = implode($this->tokens); | |
314 return $contents; | |
315 | |
316 }//end getContents() | |
317 | |
318 | |
319 /** | |
320 * Get the current fixed content of a token. | |
321 * | |
322 * This function takes changesets into account so should be used | |
323 * instead of directly accessing the token array. | |
324 * | |
325 * @param int $stackPtr The position of the token in the token stack. | |
326 * | |
327 * @return string | |
328 */ | |
329 public function getTokenContent($stackPtr) | |
330 { | |
331 if ($this->inChangeset === true | |
332 && isset($this->changeset[$stackPtr]) === true | |
333 ) { | |
334 return $this->changeset[$stackPtr]; | |
335 } else { | |
336 return $this->tokens[$stackPtr]; | |
337 } | |
338 | |
339 }//end getTokenContent() | |
340 | |
341 | |
342 /** | |
343 * Start recording actions for a changeset. | |
344 * | |
345 * @return void | |
346 */ | |
347 public function beginChangeset() | |
348 { | |
349 if ($this->inConflict === true) { | |
350 return false; | |
351 } | |
352 | |
353 if (PHP_CODESNIFFER_VERBOSITY > 1) { | |
354 $bt = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS); | |
355 $sniff = $bt[1]['class']; | |
356 $line = $bt[0]['line']; | |
357 | |
358 @ob_end_clean(); | |
359 echo "\t=> Changeset started by $sniff (line $line)".PHP_EOL; | |
360 ob_start(); | |
361 } | |
362 | |
363 $this->changeset = []; | |
364 $this->inChangeset = true; | |
365 | |
366 }//end beginChangeset() | |
367 | |
368 | |
369 /** | |
370 * Stop recording actions for a changeset, and apply logged changes. | |
371 * | |
372 * @return boolean | |
373 */ | |
374 public function endChangeset() | |
375 { | |
376 if ($this->inConflict === true) { | |
377 return false; | |
378 } | |
379 | |
380 $this->inChangeset = false; | |
381 | |
382 $success = true; | |
383 $applied = []; | |
384 foreach ($this->changeset as $stackPtr => $content) { | |
385 $success = $this->replaceToken($stackPtr, $content); | |
386 if ($success === false) { | |
387 break; | |
388 } else { | |
389 $applied[] = $stackPtr; | |
390 } | |
391 } | |
392 | |
393 if ($success === false) { | |
394 // Rolling back all changes. | |
395 foreach ($applied as $stackPtr) { | |
396 $this->revertToken($stackPtr); | |
397 } | |
398 | |
399 if (PHP_CODESNIFFER_VERBOSITY > 1) { | |
400 @ob_end_clean(); | |
401 echo "\t=> Changeset failed to apply".PHP_EOL; | |
402 ob_start(); | |
403 } | |
404 } else if (PHP_CODESNIFFER_VERBOSITY > 1) { | |
405 $fixes = count($this->changeset); | |
406 @ob_end_clean(); | |
407 echo "\t=> Changeset ended: $fixes changes applied".PHP_EOL; | |
408 ob_start(); | |
409 } | |
410 | |
411 $this->changeset = []; | |
412 | |
413 }//end endChangeset() | |
414 | |
415 | |
416 /** | |
417 * Stop recording actions for a changeset, and discard logged changes. | |
418 * | |
419 * @return void | |
420 */ | |
421 public function rollbackChangeset() | |
422 { | |
423 $this->inChangeset = false; | |
424 $this->inConflict = false; | |
425 | |
426 if (empty($this->changeset) === false) { | |
427 if (PHP_CODESNIFFER_VERBOSITY > 1) { | |
428 $bt = debug_backtrace(); | |
429 if ($bt[1]['class'] === 'PHP_CodeSniffer\Fixer') { | |
430 $sniff = $bt[2]['class']; | |
431 $line = $bt[1]['line']; | |
432 } else { | |
433 $sniff = $bt[1]['class']; | |
434 $line = $bt[0]['line']; | |
435 } | |
436 | |
437 $numChanges = count($this->changeset); | |
438 | |
439 @ob_end_clean(); | |
440 echo "\t\tR: $sniff (line $line) rolled back the changeset ($numChanges changes)".PHP_EOL; | |
441 echo "\t=> Changeset rolled back".PHP_EOL; | |
442 ob_start(); | |
443 } | |
444 | |
445 $this->changeset = []; | |
446 }//end if | |
447 | |
448 }//end rollbackChangeset() | |
449 | |
450 | |
451 /** | |
452 * Replace the entire contents of a token. | |
453 * | |
454 * @param int $stackPtr The position of the token in the token stack. | |
455 * @param string $content The new content of the token. | |
456 * | |
457 * @return bool If the change was accepted. | |
458 */ | |
459 public function replaceToken($stackPtr, $content) | |
460 { | |
461 if ($this->inConflict === true) { | |
462 return false; | |
463 } | |
464 | |
465 if ($this->inChangeset === false | |
466 && isset($this->fixedTokens[$stackPtr]) === true | |
467 ) { | |
468 $indent = "\t"; | |
469 if (empty($this->changeset) === false) { | |
470 $indent .= "\t"; | |
471 } | |
472 | |
473 if (PHP_CODESNIFFER_VERBOSITY > 1) { | |
474 @ob_end_clean(); | |
475 echo "$indent* token $stackPtr has already been modified, skipping *".PHP_EOL; | |
476 ob_start(); | |
477 } | |
478 | |
479 return false; | |
480 } | |
481 | |
482 if (PHP_CODESNIFFER_VERBOSITY > 1) { | |
483 $bt = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS); | |
484 if ($bt[1]['class'] === 'PHP_CodeSniffer\Fixer') { | |
485 $sniff = $bt[2]['class']; | |
486 $line = $bt[1]['line']; | |
487 } else { | |
488 $sniff = $bt[1]['class']; | |
489 $line = $bt[0]['line']; | |
490 } | |
491 | |
492 $tokens = $this->currentFile->getTokens(); | |
493 $type = $tokens[$stackPtr]['type']; | |
494 $oldContent = Common::prepareForOutput($this->tokens[$stackPtr]); | |
495 $newContent = Common::prepareForOutput($content); | |
496 if (trim($this->tokens[$stackPtr]) === '' && isset($this->tokens[($stackPtr + 1)]) === true) { | |
497 // Add some context for whitespace only changes. | |
498 $append = Common::prepareForOutput($this->tokens[($stackPtr + 1)]); | |
499 $oldContent .= $append; | |
500 $newContent .= $append; | |
501 } | |
502 }//end if | |
503 | |
504 if ($this->inChangeset === true) { | |
505 $this->changeset[$stackPtr] = $content; | |
506 | |
507 if (PHP_CODESNIFFER_VERBOSITY > 1) { | |
508 @ob_end_clean(); | |
509 echo "\t\tQ: $sniff (line $line) replaced token $stackPtr ($type) \"$oldContent\" => \"$newContent\"".PHP_EOL; | |
510 ob_start(); | |
511 } | |
512 | |
513 return true; | |
514 } | |
515 | |
516 if (isset($this->oldTokenValues[$stackPtr]) === false) { | |
517 $this->oldTokenValues[$stackPtr] = [ | |
518 'curr' => $content, | |
519 'prev' => $this->tokens[$stackPtr], | |
520 'loop' => $this->loops, | |
521 ]; | |
522 } else { | |
523 if ($this->oldTokenValues[$stackPtr]['prev'] === $content | |
524 && $this->oldTokenValues[$stackPtr]['loop'] === ($this->loops - 1) | |
525 ) { | |
526 if (PHP_CODESNIFFER_VERBOSITY > 1) { | |
527 $indent = "\t"; | |
528 if (empty($this->changeset) === false) { | |
529 $indent .= "\t"; | |
530 } | |
531 | |
532 $loop = $this->oldTokenValues[$stackPtr]['loop']; | |
533 | |
534 @ob_end_clean(); | |
535 echo "$indent**** $sniff (line $line) has possible conflict with another sniff on loop $loop; caused by the following change ****".PHP_EOL; | |
536 echo "$indent**** replaced token $stackPtr ($type) \"$oldContent\" => \"$newContent\" ****".PHP_EOL; | |
537 } | |
538 | |
539 if ($this->oldTokenValues[$stackPtr]['loop'] >= ($this->loops - 1)) { | |
540 $this->inConflict = true; | |
541 if (PHP_CODESNIFFER_VERBOSITY > 1) { | |
542 echo "$indent**** ignoring all changes until next loop ****".PHP_EOL; | |
543 } | |
544 } | |
545 | |
546 if (PHP_CODESNIFFER_VERBOSITY > 1) { | |
547 ob_start(); | |
548 } | |
549 | |
550 return false; | |
551 }//end if | |
552 | |
553 $this->oldTokenValues[$stackPtr]['prev'] = $this->oldTokenValues[$stackPtr]['curr']; | |
554 $this->oldTokenValues[$stackPtr]['curr'] = $content; | |
555 $this->oldTokenValues[$stackPtr]['loop'] = $this->loops; | |
556 }//end if | |
557 | |
558 $this->fixedTokens[$stackPtr] = $this->tokens[$stackPtr]; | |
559 $this->tokens[$stackPtr] = $content; | |
560 $this->numFixes++; | |
561 | |
562 if (PHP_CODESNIFFER_VERBOSITY > 1) { | |
563 $indent = "\t"; | |
564 if (empty($this->changeset) === false) { | |
565 $indent .= "\tA: "; | |
566 } | |
567 | |
568 if (ob_get_level() > 0) { | |
569 ob_end_clean(); | |
570 } | |
571 | |
572 echo "$indent$sniff (line $line) replaced token $stackPtr ($type) \"$oldContent\" => \"$newContent\"".PHP_EOL; | |
573 ob_start(); | |
574 } | |
575 | |
576 return true; | |
577 | |
578 }//end replaceToken() | |
579 | |
580 | |
581 /** | |
582 * Reverts the previous fix made to a token. | |
583 * | |
584 * @param int $stackPtr The position of the token in the token stack. | |
585 * | |
586 * @return bool If a change was reverted. | |
587 */ | |
588 public function revertToken($stackPtr) | |
589 { | |
590 if (isset($this->fixedTokens[$stackPtr]) === false) { | |
591 return false; | |
592 } | |
593 | |
594 if (PHP_CODESNIFFER_VERBOSITY > 1) { | |
595 $bt = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS); | |
596 if ($bt[1]['class'] === 'PHP_CodeSniffer\Fixer') { | |
597 $sniff = $bt[2]['class']; | |
598 $line = $bt[1]['line']; | |
599 } else { | |
600 $sniff = $bt[1]['class']; | |
601 $line = $bt[0]['line']; | |
602 } | |
603 | |
604 $tokens = $this->currentFile->getTokens(); | |
605 $type = $tokens[$stackPtr]['type']; | |
606 $oldContent = Common::prepareForOutput($this->tokens[$stackPtr]); | |
607 $newContent = Common::prepareForOutput($this->fixedTokens[$stackPtr]); | |
608 if (trim($this->tokens[$stackPtr]) === '' && isset($tokens[($stackPtr + 1)]) === true) { | |
609 // Add some context for whitespace only changes. | |
610 $append = Common::prepareForOutput($this->tokens[($stackPtr + 1)]); | |
611 $oldContent .= $append; | |
612 $newContent .= $append; | |
613 } | |
614 }//end if | |
615 | |
616 $this->tokens[$stackPtr] = $this->fixedTokens[$stackPtr]; | |
617 unset($this->fixedTokens[$stackPtr]); | |
618 $this->numFixes--; | |
619 | |
620 if (PHP_CODESNIFFER_VERBOSITY > 1) { | |
621 $indent = "\t"; | |
622 if (empty($this->changeset) === false) { | |
623 $indent .= "\tR: "; | |
624 } | |
625 | |
626 @ob_end_clean(); | |
627 echo "$indent$sniff (line $line) reverted token $stackPtr ($type) \"$oldContent\" => \"$newContent\"".PHP_EOL; | |
628 ob_start(); | |
629 } | |
630 | |
631 return true; | |
632 | |
633 }//end revertToken() | |
634 | |
635 | |
636 /** | |
637 * Replace the content of a token with a part of its current content. | |
638 * | |
639 * @param int $stackPtr The position of the token in the token stack. | |
640 * @param int $start The first character to keep. | |
641 * @param int $length The number of chacters to keep. If NULL, the content of | |
642 * the token from $start to the end of the content is kept. | |
643 * | |
644 * @return bool If the change was accepted. | |
645 */ | |
646 public function substrToken($stackPtr, $start, $length=null) | |
647 { | |
648 $current = $this->getTokenContent($stackPtr); | |
649 | |
650 if ($length === null) { | |
651 $newContent = substr($current, $start); | |
652 } else { | |
653 $newContent = substr($current, $start, $length); | |
654 } | |
655 | |
656 return $this->replaceToken($stackPtr, $newContent); | |
657 | |
658 }//end substrToken() | |
659 | |
660 | |
661 /** | |
662 * Adds a newline to end of a token's content. | |
663 * | |
664 * @param int $stackPtr The position of the token in the token stack. | |
665 * | |
666 * @return bool If the change was accepted. | |
667 */ | |
668 public function addNewline($stackPtr) | |
669 { | |
670 $current = $this->getTokenContent($stackPtr); | |
671 return $this->replaceToken($stackPtr, $current.$this->currentFile->eolChar); | |
672 | |
673 }//end addNewline() | |
674 | |
675 | |
676 /** | |
677 * Adds a newline to the start of a token's content. | |
678 * | |
679 * @param int $stackPtr The position of the token in the token stack. | |
680 * | |
681 * @return bool If the change was accepted. | |
682 */ | |
683 public function addNewlineBefore($stackPtr) | |
684 { | |
685 $current = $this->getTokenContent($stackPtr); | |
686 return $this->replaceToken($stackPtr, $this->currentFile->eolChar.$current); | |
687 | |
688 }//end addNewlineBefore() | |
689 | |
690 | |
691 /** | |
692 * Adds content to the end of a token's current content. | |
693 * | |
694 * @param int $stackPtr The position of the token in the token stack. | |
695 * @param string $content The content to add. | |
696 * | |
697 * @return bool If the change was accepted. | |
698 */ | |
699 public function addContent($stackPtr, $content) | |
700 { | |
701 $current = $this->getTokenContent($stackPtr); | |
702 return $this->replaceToken($stackPtr, $current.$content); | |
703 | |
704 }//end addContent() | |
705 | |
706 | |
707 /** | |
708 * Adds content to the start of a token's current content. | |
709 * | |
710 * @param int $stackPtr The position of the token in the token stack. | |
711 * @param string $content The content to add. | |
712 * | |
713 * @return bool If the change was accepted. | |
714 */ | |
715 public function addContentBefore($stackPtr, $content) | |
716 { | |
717 $current = $this->getTokenContent($stackPtr); | |
718 return $this->replaceToken($stackPtr, $content.$current); | |
719 | |
720 }//end addContentBefore() | |
721 | |
722 | |
723 }//end class |