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