1: <?php
2:
3: 4: 5: 6:
7:
8: namespace Latte;
9:
10:
11: 12: 13: 14:
15: class PhpHelpers
16: {
17:
18: 19: 20: 21: 22:
23: public static function reformatCode($source)
24: {
25: $res = $php = '';
26: $lastChar = ';';
27: $tokens = new \ArrayIterator(token_get_all($source));
28: $level = $openLevel = 0;
29: $lineLength = 100;
30:
31: foreach ($tokens as $n => $token) {
32: if (is_array($token)) {
33: list($name, $token) = ($tmp = $token);
34: if ($name === T_INLINE_HTML) {
35: $res .= $token;
36:
37: } elseif ($name === T_OPEN_TAG) {
38: $openLevel = $level;
39:
40: } elseif ($name === T_CLOSE_TAG) {
41: $next = isset($tokens[$n + 1]) ? $tokens[$n + 1] : null;
42: if (is_array($next) && $next[0] === T_OPEN_TAG) {
43: if (!strspn($lastChar, ';{}:/')) {
44: $php = rtrim($php) . ($lastChar = ';') . "\n" . str_repeat("\t", $level);
45: } elseif (substr($next[1], -1) === "\n") {
46: $php .= "\n" . str_repeat("\t", $level);
47: }
48: $tokens->next();
49:
50: } else {
51: if (trim($php) !== '' || substr($res, -1) === '<') {
52: $inline = strpos($php, "\n") === false && strlen($res) - strrpos($res, "\n") < $lineLength;
53: $res .= '<?php' . ($inline ? ' ' : "\n" . str_repeat("\t", $openLevel));
54: if (is_array($next) && strpos($next[1], "\n") === false) {
55: $token = rtrim($token, "\n");
56: } else {
57: $php = rtrim($php, "\t");
58: }
59: $res .= $php . $token;
60: }
61: $php = '';
62: $lastChar = ';';
63: }
64:
65: } elseif ($name === T_ELSE || $name === T_ELSEIF) {
66: if ($tokens[$n + 1] === ':' && $lastChar === '}') {
67: $php .= ';';
68: }
69: $lastChar = '';
70: $php .= $token;
71:
72: } elseif ($name === T_DOC_COMMENT || $name === T_COMMENT) {
73: $php .= preg_replace("#\n[ \t]*+(?!\n)#", "\n" . str_repeat("\t", $level), $token);
74:
75: } elseif ($name === T_WHITESPACE) {
76: $prev = $tokens[$n - 1];
77: $lines = substr_count($token, "\n");
78: if ($prev === '{' || $prev === '}' || $prev === ';' || $lines) {
79: $token = str_repeat("\n", max(1, $lines)) . str_repeat("\t", $level);
80: } elseif ($prev[0] === T_OPEN_TAG) {
81: $token = '';
82: }
83: $php .= $token;
84:
85: } else {
86: if (in_array($name, [T_CURLY_OPEN, T_DOLLAR_OPEN_CURLY_BRACES], true)) {
87: $level++;
88: }
89: $lastChar = '';
90: $php .= $token;
91: }
92: } else {
93: if ($token === '{' || $token === '[') {
94: $level++;
95: } elseif ($token === '}' || $token === ']') {
96: $level--;
97: $php .= "\x08";
98: } elseif ($token === ';' && !(isset($tokens[$n + 1]) && $tokens[$n + 1][0] === T_WHITESPACE)) {
99: $token .= "\n" . str_repeat("\t", $level);
100: }
101: $lastChar = $token;
102: $php .= $token;
103: }
104: }
105:
106: if ($php) {
107: $res .= "<?php\n" . str_repeat("\t", $openLevel) . $php;
108: }
109: $res = str_replace(["\t\x08", "\x08"], '', $res);
110: return $res;
111: }
112:
113:
114: public static function dump($value)
115: {
116: if (is_array($value)) {
117: $s = "[\n";
118: foreach ($value as $k => $v) {
119: $v = is_array($v) && (!$v || array_keys($v) === range(0, count($v) - 1))
120: ? '[' . implode(', ', array_map(function ($s) { return var_export($s, true); }, $v)) . ']'
121: : var_export($v, true);
122: $s .= "\t\t" . var_export($k, true) . ' => ' . $v . ",\n";
123: }
124: return $s . "\t]";
125: }
126: return var_export($value, true);
127: }
128: }
129: