Namespaces

  • Latte
    • Loaders
    • Macros
    • Runtime
  • Nette
    • Application
      • Responses
      • Routers
      • UI
    • Bridges
      • ApplicationLatte
      • ApplicationTracy
      • CacheLatte
      • DatabaseDI
      • DatabaseTracy
      • DITracy
      • FormsLatte
      • Framework
      • HttpTracy
      • SecurityTracy
    • Caching
      • Storages
    • ComponentModel
    • Database
      • Drivers
      • Reflection
      • Table
    • DI
      • Config
        • Adapters
      • Extensions
    • Diagnostics
    • Forms
      • Controls
      • Rendering
    • Http
    • Iterators
    • Latte
    • Loaders
    • Localization
    • Mail
    • Neon
    • PhpGenerator
    • Reflection
    • Security
    • Templating
    • Utils
  • NetteModule
  • none
  • Tracy

Classes

  • CachingIterator
  • Filters
  • Html

Interfaces

  • IHtmlString
  • Overview
  • Namespace
  • Class
  • Tree
  • Deprecated
  1: <?php
  2: 
  3: /**
  4:  * This file is part of the Nette Framework (http://nette.org)
  5:  * Copyright (c) 2004 David Grudl (http://davidgrudl.com)
  6:  */
  7: 
  8: namespace Latte\Runtime;
  9: 
 10: use Latte;
 11: 
 12: 
 13: /**
 14:  * Template filters.
 15:  *
 16:  * @author     David Grudl
 17:  */
 18: class Filters
 19: {
 20:     /** @var string default date format */
 21:     public static $dateFormat = '%x';
 22: 
 23:     /** @var bool  use XHTML syntax? */
 24:     public static $xhtml = FALSE;
 25: 
 26: 
 27:     /**
 28:      * Escapes string for use inside HTML template.
 29:      * @param  mixed  UTF-8 encoding
 30:      * @param  int    optional attribute quotes
 31:      * @return string
 32:      */
 33:     public static function escapeHtml($s, $quotes = ENT_QUOTES)
 34:     {
 35:         if ($s instanceof IHtmlString || $s instanceof \Nette\Utils\IHtmlString) {
 36:             return $s->__toString(TRUE);
 37:         }
 38:         $s = (string) $s;
 39:         if ($quotes !== ENT_NOQUOTES && strpos($s, '`') !== FALSE && strpbrk($s, ' <>"\'') === FALSE) {
 40:             $s .= ' ';
 41:         }
 42:         return htmlSpecialChars($s, $quotes);
 43:     }
 44: 
 45: 
 46:     /**
 47:      * Escapes string for use inside HTML comments.
 48:      * @param  string  UTF-8 encoding
 49:      * @return string
 50:      */
 51:     public static function escapeHtmlComment($s)
 52:     {
 53:         $s = (string) $s;
 54:         if ($s && ($s[0] === '-' || $s[0] === '>' || $s[0] === '!')) {
 55:             $s = ' ' . $s;
 56:         }
 57:         return str_replace('-', '- ', $s); // dash is very problematic character in comments
 58:     }
 59: 
 60: 
 61:     /**
 62:      * Escapes string for use inside XML 1.0 template.
 63:      * @param  string UTF-8 encoding
 64:      * @return string
 65:      */
 66:     public static function escapeXML($s)
 67:     {
 68:         // XML 1.0: \x09 \x0A \x0D and C1 allowed directly, C0 forbidden
 69:         // XML 1.1: \x00 forbidden directly and as a character reference,
 70:         //   \x09 \x0A \x0D \x85 allowed directly, C0, C1 and \x7F allowed as character references
 71:         return htmlSpecialChars(preg_replace('#[\x00-\x08\x0B\x0C\x0E-\x1F]+#', '', $s), ENT_QUOTES);
 72:     }
 73: 
 74: 
 75:     /**
 76:      * Escapes string for use inside CSS template.
 77:      * @param  string UTF-8 encoding
 78:      * @return string
 79:      */
 80:     public static function escapeCss($s)
 81:     {
 82:         // http://www.w3.org/TR/2006/WD-CSS21-20060411/syndata.html#q6
 83:         return addcslashes($s, "\x00..\x1F!\"#$%&'()*+,./:;<=>?@[\\]^`{|}~");
 84:     }
 85: 
 86: 
 87:     /**
 88:      * Escapes variables for use inside <script>.
 89:      * @param  mixed  UTF-8 encoding
 90:      * @return string
 91:      */
 92:     public static function escapeJs($s)
 93:     {
 94:         if ($s instanceof IHtmlString || $s instanceof \Nette\Utils\IHtmlString) {
 95:             $s = $s->__toString(TRUE);
 96:         }
 97: 
 98:         $json = json_encode($s, PHP_VERSION_ID >= 50400 ? JSON_UNESCAPED_UNICODE : 0);
 99:         if ($error = json_last_error()) {
100:             throw new \RuntimeException(PHP_VERSION_ID >= 50500 ? json_last_error_msg() : 'JSON encode error', $error);
101:         }
102: 
103:         return str_replace(array("\xe2\x80\xa8", "\xe2\x80\xa9", ']]>', '<!'), array('\u2028', '\u2029', ']]\x3E', '\x3C!'), $json);
104:     }
105: 
106: 
107:     /**
108:      * Escapes string for use inside iCal template.
109:      * @param  mixed  UTF-8 encoding
110:      * @return string
111:      */
112:     public static function escapeICal($s)
113:     {
114:         // http://www.ietf.org/rfc/rfc5545.txt
115:         return addcslashes(preg_replace('#[\x00-\x08\x0B\x0C-\x1F]+#', '', $s), "\";\\,:\n");
116:     }
117: 
118: 
119:     /**
120:      * Sanitizes string for use inside href attribute.
121:      * @param  string
122:      * @return string
123:      */
124:     public static function safeUrl($s)
125:     {
126:         return preg_match('~^(?:(?:https?|ftp)://[^@]+(?:/.*)?|mailto:.+|[/?#].*|[^:]+)\z~i', $s) ? $s : '';
127:     }
128: 
129: 
130:     /**
131:      * Replaces all repeated white spaces with a single space.
132:      * @param  string UTF-8 encoding or 8-bit
133:      * @return string
134:      */
135:     public static function strip($s)
136:     {
137:         return preg_replace_callback(
138:             '#(</textarea|</pre|</script|^).*?(?=<textarea|<pre|<script|\z)#si',
139:             function($m) {
140:                 return trim(preg_replace('#[ \t\r\n]+#', ' ', $m[0]));
141:             },
142:             $s
143:         );
144:     }
145: 
146: 
147:     /**
148:      * Indents the HTML content from the left.
149:      * @param  string UTF-8 encoding or 8-bit
150:      * @param  int
151:      * @param  string
152:      * @return string
153:      */
154:     public static function indent($s, $level = 1, $chars = "\t")
155:     {
156:         if ($level >= 1) {
157:             $s = preg_replace_callback('#<(textarea|pre).*?</\\1#si', function($m) {
158:                 return strtr($m[0], " \t\r\n", "\x1F\x1E\x1D\x1A");
159:             }, $s);
160:             if (preg_last_error()) {
161:                 throw new Latte\RegexpException(NULL, preg_last_error());
162:             }
163:             $s = preg_replace('#(?:^|[\r\n]+)(?=[^\r\n])#', '$0' . str_repeat($chars, $level), $s);
164:             $s = strtr($s, "\x1F\x1E\x1D\x1A", " \t\r\n");
165:         }
166:         return $s;
167:     }
168: 
169: 
170:     /**
171:      * Date/time formatting.
172:      * @param  string|int|DateTime|DateInterval
173:      * @param  string
174:      * @return string
175:      */
176:     public static function date($time, $format = NULL)
177:     {
178:         if ($time == NULL) { // intentionally ==
179:             return NULL;
180:         }
181: 
182:         if (!isset($format)) {
183:             $format = self::$dateFormat;
184:         }
185: 
186:         if ($time instanceof \DateInterval) {
187:             return $time->format($format);
188: 
189:         } elseif (!$time instanceof \DateTime && !$time instanceof \DateTimeInterface) {
190:             $time = new \DateTime((is_numeric($time) ? '@' : '') . $time);
191:         }
192:         return strpos($format, '%') === FALSE
193:             ? $time->format($format) // formats using date()
194:             : strftime($format, $time->format('U')); // formats according to locales
195:     }
196: 
197: 
198:     /**
199:      * Converts to human readable file size.
200:      * @param  int
201:      * @param  int
202:      * @return string
203:      */
204:     public static function bytes($bytes, $precision = 2)
205:     {
206:         $bytes = round($bytes);
207:         $units = array('B', 'kB', 'MB', 'GB', 'TB', 'PB');
208:         foreach ($units as $unit) {
209:             if (abs($bytes) < 1024 || $unit === end($units)) {
210:                 break;
211:             }
212:             $bytes = $bytes / 1024;
213:         }
214:         return round($bytes, $precision) . ' ' . $unit;
215:     }
216: 
217: 
218:     /**
219:      * Performs a search and replace.
220:      * @param  string
221:      * @param  string
222:      * @param  string
223:      * @return string
224:      */
225:     public static function replace($subject, $search, $replacement = '')
226:     {
227:         return str_replace($search, $replacement, $subject);
228:     }
229: 
230: 
231:     /**
232:      * Perform a regular expression search and replace.
233:      * @param  string
234:      * @param  string
235:      * @return string
236:      */
237:     public static function replaceRe($subject, $pattern, $replacement = '')
238:     {
239:         $res = preg_replace($pattern, $replacement, $subject);
240:         if (preg_last_error()) {
241:             throw new Latte\RegexpException(NULL, preg_last_error());
242:         }
243:         return $res;
244:     }
245: 
246: 
247:     /**
248:      * The data: URI generator.
249:      * @param  string
250:      * @param  string
251:      * @return string
252:      */
253:     public static function dataStream($data, $type = NULL)
254:     {
255:         if ($type === NULL) {
256:             $type = finfo_buffer(finfo_open(FILEINFO_MIME_TYPE), $data);
257:         }
258:         return 'data:' . ($type ? "$type;" : '') . 'base64,' . base64_encode($data);
259:     }
260: 
261: 
262:     /**
263:      * @param  string
264:      * @return string
265:      */
266:     public static function nl2br($value)
267:     {
268:         return nl2br($value, self::$xhtml);
269:     }
270: 
271: 
272:     /**
273:      * Returns a part of UTF-8 string.
274:      * @param  string
275:      * @param  int
276:      * @param  int
277:      * @return string
278:      */
279:     public static function substring($s, $start, $length = NULL)
280:     {
281:         if ($length === NULL) {
282:             $length = self::length($s);
283:         }
284:         if (function_exists('mb_substr')) {
285:             return mb_substr($s, $start, $length, 'UTF-8'); // MB is much faster
286:         }
287:         return iconv_substr($s, $start, $length, 'UTF-8');
288:     }
289: 
290: 
291:     /**
292:      * Truncates string to maximal length.
293:      * @param  string  UTF-8 encoding
294:      * @param  int
295:      * @param  string  UTF-8 encoding
296:      * @return string
297:      */
298:     public static function truncate($s, $maxLen, $append = "\xE2\x80\xA6")
299:     {
300:         if (self::length($s) > $maxLen) {
301:             $maxLen = $maxLen - self::length($append);
302:             if ($maxLen < 1) {
303:                 return $append;
304: 
305:             } elseif (preg_match('#^.{1,'.$maxLen.'}(?=[\s\x00-/:-@\[-`{-~])#us', $s, $matches)) {
306:                 return $matches[0] . $append;
307: 
308:             } else {
309:                 return self::substring($s, 0, $maxLen) . $append;
310:             }
311:         }
312:         return $s;
313:     }
314: 
315: 
316:     /**
317:      * Convert to lower case.
318:      * @return string
319:      */
320:     public static function lower($s)
321:     {
322:         return mb_strtolower($s, 'UTF-8');
323:     }
324: 
325: 
326:     /**
327:      * Convert to upper case.
328:      * @return string
329:      */
330:     public static function upper($s)
331:     {
332:         return mb_strtoupper($s, 'UTF-8');
333:     }
334: 
335: 
336:     /**
337:      * Convert first character to upper case.
338:      * @return string
339:      */
340:     public static function firstUpper($s)
341:     {
342:         return self::upper(self::substring($s, 0, 1)) . self::substring($s, 1);
343:     }
344: 
345: 
346:     /**
347:      * Capitalize string.
348:      * @return string
349:      */
350:     public static function capitalize($s)
351:     {
352:         return mb_convert_case($s, MB_CASE_TITLE, 'UTF-8');
353:     }
354: 
355: 
356:     /**
357:      * Returns UTF-8 string length.
358:      * @return int
359:      */
360:     public static function length($s)
361:     {
362:         return strlen(utf8_decode($s)); // fastest way
363:     }
364: 
365: 
366:     /**
367:      * Strips whitespace.
368:      * @param  string  UTF-8 encoding
369:      * @param  string
370:      * @return string
371:      */
372:     public static function trim($s, $charlist = " \t\n\r\0\x0B\xC2\xA0")
373:     {
374:         $charlist = preg_quote($charlist, '#');
375:         $s = preg_replace('#^['.$charlist.']+|['.$charlist.']+\z#u', '', $s);
376:         if (preg_last_error()) {
377:             throw new Latte\RegexpException(NULL, preg_last_error());
378:         }
379:         return $s;
380:     }
381: 
382: 
383:     /**
384:      * Returns element's attributes.
385:      * @return string
386:      */
387:     public static function htmlAttributes($attrs)
388:     {
389:         if (!is_array($attrs)) {
390:             return '';
391:         }
392: 
393:         $s = '';
394:         foreach ($attrs as $key => $value) {
395:             if ($value === NULL || $value === FALSE) {
396:                 continue;
397: 
398:             } elseif ($value === TRUE) {
399:                 if (static::$xhtml) {
400:                     $s .= ' ' . $key . '="' . $key . '"';
401:                 } else {
402:                     $s .= ' ' . $key;
403:                 }
404:                 continue;
405: 
406:             } elseif (is_array($value)) {
407:                 $tmp = NULL;
408:                 foreach ($value as $k => $v) {
409:                     if ($v != NULL) { // intentionally ==, skip NULLs & empty string
410:                         //  composite 'style' vs. 'others'
411:                         $tmp[] = $v === TRUE ? $k : (is_string($k) ? $k . ':' . $v : $v);
412:                     }
413:                 }
414:                 if ($tmp === NULL) {
415:                     continue;
416:                 }
417: 
418:                 $value = implode($key === 'style' || !strncmp($key, 'on', 2) ? ';' : ' ', $tmp);
419: 
420:             } else {
421:                 $value = (string) $value;
422:             }
423: 
424:             $q = strpos($value, '"') === FALSE ? '"' : "'";
425:             $s .= ' ' . $key . '='
426:                 . $q . str_replace(array('&', $q), array('&amp;', $q === '"' ? '&quot;' : '&#39;'), $value)
427:                 . (strpos($value, '`') !== FALSE && strpbrk($value, ' <>"\'') === FALSE ? ' ' : '')
428:                 . $q;
429:         }
430:         return $s;
431:     }
432: 
433: }
434: 
Nette 2.2.2 API API documentation generated by ApiGen 2.8.0