1: <?php
2:
3: 4: 5: 6: 7: 8: 9: 10:
11:
12: namespace Nette\Templating;
13:
14: use Nette,
15: Nette\Utils\Strings,
16: Nette\Forms\Form,
17: Nette\Utils\Html;
18:
19:
20:
21: 22: 23: 24: 25:
26: final class Helpers
27: {
28: private static $helpers = array(
29: 'normalize' => 'Nette\Utils\Strings::normalize',
30: 'toascii' => 'Nette\Utils\Strings::toAscii',
31: 'webalize' => 'Nette\Utils\Strings::webalize',
32: 'truncate' => 'Nette\Utils\Strings::truncate',
33: 'lower' => 'Nette\Utils\Strings::lower',
34: 'upper' => 'Nette\Utils\Strings::upper',
35: 'firstupper' => 'Nette\Utils\Strings::firstUpper',
36: 'capitalize' => 'Nette\Utils\Strings::capitalize',
37: 'trim' => 'Nette\Utils\Strings::trim',
38: 'padleft' => 'Nette\Utils\Strings::padLeft',
39: 'padright' => 'Nette\Utils\Strings::padRight',
40: 'reverse' => 'Nette\Utils\Strings::reverse',
41: 'replacere' => 'Nette\Utils\Strings::replace',
42: 'url' => 'rawurlencode',
43: 'striptags' => 'strip_tags',
44: 'nl2br' => 'nl2br',
45: 'substr' => 'Nette\Utils\Strings::substring',
46: 'repeat' => 'str_repeat',
47: 'implode' => 'implode',
48: 'number' => 'number_format',
49: );
50:
51:
52: public static $dateFormat = '%x';
53:
54:
55:
56: 57: 58: 59: 60:
61: public static function loader($helper)
62: {
63: if (method_exists(__CLASS__, $helper)) {
64: return new Nette\Callback(__CLASS__, $helper);
65: } elseif (isset(self::$helpers[$helper])) {
66: return self::$helpers[$helper];
67: }
68: }
69:
70:
71:
72: 73: 74: 75: 76: 77:
78: public static function escapeHtml($s, $quotes = ENT_QUOTES)
79: {
80: if (is_object($s) && ($s instanceof ITemplate || $s instanceof Html || $s instanceof Form)) {
81: return $s->__toString(TRUE);
82: }
83: return htmlSpecialChars($s, $quotes);
84: }
85:
86:
87:
88: 89: 90: 91: 92:
93: public static function escapeHtmlComment($s)
94: {
95:
96: return str_replace('--', '--><!-- ', $s);
97: }
98:
99:
100:
101: 102: 103: 104: 105:
106: public static function escapeXML($s)
107: {
108:
109:
110:
111: return htmlSpecialChars(preg_replace('#[\x00-\x08\x0B\x0C\x0E-\x1F]+#', '', $s), ENT_QUOTES);
112: }
113:
114:
115:
116: 117: 118: 119: 120:
121: public static function escapeCss($s)
122: {
123:
124: return addcslashes($s, "\x00..\x1F!\"#$%&'()*+,./:;<=>?@[\\]^`{|}~");
125: }
126:
127:
128:
129: 130: 131: 132: 133:
134: public static function escapeJs($s)
135: {
136: if (is_object($s) && ($s instanceof ITemplate || $s instanceof Html || $s instanceof Form)) {
137: $s = $s->__toString(TRUE);
138: }
139: return str_replace(']]>', ']]\x3E', Nette\Utils\Json::encode($s));
140: }
141:
142:
143:
144: 145: 146: 147: 148:
149: public static function escapeICal($s)
150: {
151:
152: return addcslashes(preg_replace('#[\x00-\x08\x0B\x0C-\x1F]+#', '', $s), "\";\\,:\n");
153: }
154:
155:
156:
157: 158: 159: 160: 161:
162: public static function strip($s)
163: {
164: return Strings::replace(
165: $s,
166: '#(</textarea|</pre|</script|^).*?(?=<textarea|<pre|<script|$)#si',
167: function($m) {
168: return trim(preg_replace("#[ \t\r\n]+#", " ", $m[0]));
169: });
170: }
171:
172:
173:
174: 175: 176: 177: 178: 179: 180:
181: public static function indent($s, $level = 1, $chars = "\t")
182: {
183: if ($level >= 1) {
184: $s = Strings::replace($s, '#<(textarea|pre).*?</\\1#si', function($m) {
185: return strtr($m[0], " \t\r\n", "\x1F\x1E\x1D\x1A");
186: });
187: $s = Strings::indent($s, $level, $chars);
188: $s = strtr($s, "\x1F\x1E\x1D\x1A", " \t\r\n");
189: }
190: return $s;
191: }
192:
193:
194:
195: 196: 197: 198: 199: 200:
201: public static function date($time, $format = NULL)
202: {
203: if ($time == NULL) {
204: return NULL;
205: }
206:
207: if (!isset($format)) {
208: $format = self::$dateFormat;
209: }
210:
211: $time = Nette\DateTime::from($time);
212: return Strings::contains($format, '%')
213: ? strftime($format, $time->format('U'))
214: : $time->format($format);
215: }
216:
217:
218:
219: 220: 221: 222: 223: 224:
225: public static function bytes($bytes, $precision = 2)
226: {
227: $bytes = round($bytes);
228: $units = array('B', 'kB', 'MB', 'GB', 'TB', 'PB');
229: foreach ($units as $unit) {
230: if (abs($bytes) < 1024 || $unit === end($units)) {
231: break;
232: }
233: $bytes = $bytes / 1024;
234: }
235: return round($bytes, $precision) . ' ' . $unit;
236: }
237:
238:
239:
240: 241: 242: 243: 244:
245: public static function length($var)
246: {
247: return is_string($var) ? Strings::length($var) : count($var);
248: }
249:
250:
251:
252: 253: 254: 255: 256: 257: 258:
259: public static function replace($subject, $search, $replacement = '')
260: {
261: return str_replace($search, $replacement, $subject);
262: }
263:
264:
265:
266: 267: 268: 269: 270: 271:
272: public static function dataStream($data, $type = NULL)
273: {
274: if ($type === NULL) {
275: $type = Nette\Utils\MimeTypeDetector::fromString($data);
276: }
277: return 'data:' . ($type ? "$type;" : '') . 'base64,' . base64_encode($data);
278: }
279:
280:
281:
282: 283: 284: 285: 286:
287: public static function null($value)
288: {
289: return '';
290: }
291:
292:
293:
294:
295:
296:
297:
298: 299: 300: 301: 302:
303: public static function optimizePhp($source, $lineLength = 80, $existenceOfThisParameterSolvesDamnBugInPHP535 = NULL)
304: {
305: $res = $php = '';
306: $lastChar = ';';
307: $tokens = new \ArrayIterator(token_get_all($source));
308: foreach ($tokens as $key => $token) {
309: if (is_array($token)) {
310: if ($token[0] === T_INLINE_HTML) {
311: $lastChar = '';
312: $res .= $token[1];
313:
314: } elseif ($token[0] === T_CLOSE_TAG) {
315: $next = isset($tokens[$key + 1]) ? $tokens[$key + 1] : NULL;
316: if (substr($res, -1) !== '<' && preg_match('#^<\?php\s*$#', $php)) {
317: $php = '';
318:
319: } elseif (is_array($next) && $next[0] === T_OPEN_TAG) {
320: if (!strspn($lastChar, ';{}:/')) {
321: $php .= $lastChar = ';';
322: }
323: if (substr($next[1], -1) === "\n") {
324: $php .= "\n";
325: }
326: $tokens->next();
327:
328: } elseif ($next) {
329: $res .= preg_replace('#;?(\s)*$#', '$1', $php) . $token[1];
330: if (strlen($res) - strrpos($res, "\n") > $lineLength
331: && (!is_array($next) || strpos($next[1], "\n") === FALSE)
332: ) {
333: $res .= "\n";
334: }
335: $php = '';
336:
337: } else {
338: if (!strspn($lastChar, '};')) {
339: $php .= ';';
340: }
341: }
342:
343: } elseif ($token[0] === T_ELSE || $token[0] === T_ELSEIF) {
344: if ($tokens[$key + 1] === ':' && $lastChar === '}') {
345: $php .= ';';
346: }
347: $lastChar = '';
348: $php .= $token[1];
349:
350: } else {
351: if (!in_array($token[0], array(T_WHITESPACE, T_COMMENT, T_DOC_COMMENT, T_OPEN_TAG))) {
352: $lastChar = '';
353: }
354: $php .= $token[1];
355: }
356: } else {
357: $php .= $lastChar = $token;
358: }
359: }
360: return $res . $php;
361: }
362:
363: }
364: