Commit | Line | Data |
---|---|---|
c3fc2621 CW |
1 | <?php |
2 | ||
3 | /** | |
4 | * Class CRM_Core_CodeGen_Util_ArraySyntaxConverter | |
5 | * | |
6 | * @link https://github.com/thomasbachem/php-short-array-syntax-converter | |
7 | * | |
8 | * @license http://www.gnu.org/licenses/lgpl.html | |
9 | * @author Thomas Bachem <mail@thomasbachem.com> | |
10 | */ | |
11 | class CRM_Core_CodeGen_Util_ArraySyntaxConverter { | |
12 | ||
13 | /** | |
14 | * @param string $code | |
15 | * @return string | |
16 | */ | |
17 | public static function convert($code) { | |
18 | $tokens = token_get_all($code); | |
19 | ||
20 | // - - - - - PARSE CODE - - - - - | |
be2fb01f | 21 | $replacements = []; |
c3fc2621 CW |
22 | $offset = 0; |
23 | for ($i = 0; $i < count($tokens); ++$i) { | |
24 | // Keep track of the current byte offset in the source code | |
25 | $offset += strlen(is_array($tokens[$i]) ? $tokens[$i][1] : $tokens[$i]); | |
26 | // T_ARRAY could either mean the "array(...)" syntax we're looking for | |
27 | // or a type hinting statement ("function(array $foo) { ... }") | |
28 | if (is_array($tokens[$i]) && $tokens[$i][0] === T_ARRAY) { | |
29 | // Look for a subsequent opening bracket ("(") to be sure we're actually | |
30 | // looking at an "array(...)" statement | |
31 | $isArraySyntax = FALSE; | |
32 | $subOffset = $offset; | |
33 | for ($j = $i + 1; $j < count($tokens); ++$j) { | |
34 | $subOffset += strlen(is_array($tokens[$j]) ? $tokens[$j][1] : $tokens[$j]); | |
35 | if (is_string($tokens[$j]) && $tokens[$j] == '(') { | |
36 | $isArraySyntax = TRUE; | |
37 | break; | |
38 | } | |
39 | elseif (!is_array($tokens[$j]) || $tokens[$j][0] !== T_WHITESPACE) { | |
40 | $isArraySyntax = FALSE; | |
41 | break; | |
42 | } | |
43 | } | |
44 | if ($isArraySyntax) { | |
45 | // Replace "array" and the opening bracket (including preceeding whitespace) with "[" | |
be2fb01f | 46 | $replacements[] = [ |
c3fc2621 CW |
47 | 'start' => $offset - strlen($tokens[$i][1]), |
48 | 'end' => $subOffset, | |
49 | 'string' => '[', | |
be2fb01f | 50 | ]; |
c3fc2621 CW |
51 | // Look for matching closing bracket (")") |
52 | $subOffset = $offset; | |
53 | $openBracketsCount = 0; | |
54 | for ($j = $i + 1; $j < count($tokens); ++$j) { | |
55 | $subOffset += strlen(is_array($tokens[$j]) ? $tokens[$j][1] : $tokens[$j]); | |
56 | if (is_string($tokens[$j]) && $tokens[$j] == '(') { | |
57 | ++$openBracketsCount; | |
58 | } | |
59 | elseif (is_string($tokens[$j]) && $tokens[$j] == ')') { | |
60 | --$openBracketsCount; | |
61 | if ($openBracketsCount == 0) { | |
62 | // Replace ")" with "]" | |
be2fb01f | 63 | $replacements[] = [ |
c3fc2621 CW |
64 | 'start' => $subOffset - 1, |
65 | 'end' => $subOffset, | |
66 | 'string' => ']', | |
be2fb01f | 67 | ]; |
c3fc2621 CW |
68 | break; |
69 | } | |
70 | } | |
71 | } | |
72 | } | |
73 | } | |
74 | } | |
75 | ||
76 | // - - - - - UPDATE CODE - - - - - | |
77 | // Apply the replacements to the source code | |
78 | $offsetChange = 0; | |
79 | foreach ($replacements as $replacement) { | |
80 | $code = substr_replace( | |
81 | $code, | |
82 | $replacement['string'], | |
83 | $replacement['start'] + $offsetChange, | |
84 | $replacement['end'] - $replacement['start'] | |
85 | ); | |
86 | $offsetChange += strlen($replacement['string']) - ($replacement['end'] - $replacement['start']); | |
87 | } | |
88 | ||
89 | return $code; | |
90 | } | |
91 | ||
92 | } |