Packages

  • Nette
    • Application
      • Diagnostics
      • Responses
      • Routers
      • UI
    • Caching
      • Storages
    • ComponentModel
    • Config
      • Adapters
      • Extensions
    • Database
      • Diagnostics
      • Drivers
      • Reflection
      • Table
    • DI
      • Diagnostics
    • Diagnostics
    • Forms
      • Controls
      • Rendering
    • Http
    • Iterators
    • Latte
      • Macros
    • Loaders
    • Localization
    • Mail
    • Reflection
    • Security
      • Diagnostics
    • Templating
    • Utils
      • PhpGenerator
  • NetteModule
  • none

Classes

Interfaces

Exceptions

  • Overview
  • Package
  • Class
  • Tree
  • Deprecated
  • Other releases
  • Nette homepage
  1: <?php
  2: 
  3: /**
  4:  * This file is part of the Nette Framework (https://nette.org)
  5:  * Copyright (c) 2004 David Grudl (http://davidgrudl.com)
  6:  * @package Nette\Templating
  7:  */
  8: 
  9: 
 10: 
 11: /**
 12:  * Template helpers.
 13:  *
 14:  * @author     David Grudl
 15:  * @package Nette\Templating
 16:  */
 17: class NTemplateHelpers
 18: {
 19:     private static $helpers = array(
 20:         'normalize' => 'NStrings::normalize',
 21:         'toascii' => 'NStrings::toAscii',
 22:         'webalize' => 'NStrings::webalize',
 23:         'truncate' => 'NStrings::truncate',
 24:         'lower' => 'NStrings::lower',
 25:         'upper' => 'NStrings::upper',
 26:         'firstupper' => 'NStrings::firstUpper',
 27:         'capitalize' => 'NStrings::capitalize',
 28:         'trim' => 'NStrings::trim',
 29:         'padleft' => 'NStrings::padLeft',
 30:         'padright' => 'NStrings::padRight',
 31:         'reverse' =>  'NStrings::reverse',
 32:         'replacere' => 'NStrings::replace',
 33:         'url' => 'rawurlencode',
 34:         'striptags' => 'strip_tags',
 35:         'substr' => 'NStrings::substring',
 36:         'repeat' => 'str_repeat',
 37:         'implode' => 'implode',
 38:         'number' => 'number_format',
 39:     );
 40: 
 41:     /** @var string default date format */
 42:     public static $dateFormat = '%x';
 43: 
 44: 
 45:     /**
 46:      * Try to load the requested helper.
 47:      * @param  string  helper name
 48:      * @return callable
 49:      */
 50:     public static function loader($helper)
 51:     {
 52:         if (method_exists(__CLASS__, $helper)) {
 53:             return new NCallback(__CLASS__, $helper);
 54:         } elseif (isset(self::$helpers[$helper])) {
 55:             return self::$helpers[$helper];
 56:         }
 57:     }
 58: 
 59: 
 60:     /**
 61:      * Escapes string for use inside HTML template.
 62:      * @param  mixed  UTF-8 encoding
 63:      * @param  int    optional attribute quotes
 64:      * @return string
 65:      */
 66:     public static function escapeHtml($s, $quotes = ENT_QUOTES)
 67:     {
 68:         if ($quotes === ENT_NOQUOTES && ($s instanceof ITemplate || $s instanceof NHtml || $s instanceof NForm)) {
 69:             return $s->__toString(TRUE);
 70:         }
 71:         $s = (string) $s;
 72:         if ($quotes !== ENT_NOQUOTES && strpos($s, '`') !== FALSE && strpbrk($s, ' <>"\'') === FALSE) {
 73:             $s .= ' ';
 74:         }
 75:         return htmlSpecialChars($s, $quotes);
 76:     }
 77: 
 78: 
 79:     /**
 80:      * Escapes string for use inside HTML comments.
 81:      * @param  string  UTF-8 encoding
 82:      * @return string
 83:      */
 84:     public static function escapeHtmlComment($s)
 85:     {
 86:         $s = (string) $s;
 87:         if ($s && ($s[0] === '-' || $s[0] === '>' || $s[0] === '!')) {
 88:             $s = ' ' . $s;
 89:         }
 90:         return str_replace('-', '- ', $s); // dash is very problematic character in comments
 91:     }
 92: 
 93: 
 94:     /**
 95:      * Escapes string for use inside XML 1.0 template.
 96:      * @param  string UTF-8 encoding
 97:      * @return string
 98:      */
 99:     public static function escapeXML($s)
100:     {
101:         // XML 1.0: \x09 \x0A \x0D and C1 allowed directly, C0 forbidden
102:         // XML 1.1: \x00 forbidden directly and as a character reference,
103:         //   \x09 \x0A \x0D \x85 allowed directly, C0, C1 and \x7F allowed as character references
104:         return htmlSpecialChars(preg_replace('#[\x00-\x08\x0B\x0C\x0E-\x1F]+#', '', $s), ENT_QUOTES);
105:     }
106: 
107: 
108:     /**
109:      * Escapes string for use inside CSS template.
110:      * @param  string UTF-8 encoding
111:      * @return string
112:      */
113:     public static function escapeCss($s)
114:     {
115:         // http://www.w3.org/TR/2006/WD-CSS21-20060411/syndata.html#q6
116:         return addcslashes($s, "\x00..\x1F!\"#$%&'()*+,./:;<=>?@[\\]^`{|}~");
117:     }
118: 
119: 
120:     /**
121:      * Escapes variables for use inside <script>.
122:      * @param  mixed  UTF-8 encoding
123:      * @return string
124:      */
125:     public static function escapeJs($s)
126:     {
127:         if (is_object($s) && ($s instanceof ITemplate || $s instanceof NHtml || $s instanceof NForm)) {
128:             $s = $s->__toString(TRUE);
129:         }
130:         return str_replace(array(']]>', '<!'), array(']]\x3E', '\x3C!'), NJson::encode($s));
131:     }
132: 
133: 
134:     /**
135:      * Escapes string for use inside iCal template.
136:      * @param  mixed  UTF-8 encoding
137:      * @return string
138:      */
139:     public static function escapeICal($s)
140:     {
141:         // http://www.ietf.org/rfc/rfc5545.txt
142:         return addcslashes(preg_replace('#[\x00-\x08\x0B\x0C-\x1F]+#', '', $s), "\";\\,:\n");
143:     }
144: 
145: 
146:     /**
147:      * Sanitizes string for use inside href attribute.
148:      * @param  string
149:      * @return string
150:      */
151:     public static function safeUrl($s)
152:     {
153:         return preg_match('~^(?:(?:https?|ftp)://[^@]+(?:/.*)?|mailto:.+|[/?#].*|[^:]+)\z~i', $s) ? $s : '';
154:     }
155: 
156: 
157:     /**
158:      * Replaces all repeated white spaces with a single space.
159:      * @param  string UTF-8 encoding or 8-bit
160:      * @return string
161:      */
162:     public static function strip($s)
163:     {
164:         return NStrings::replace(
165:             $s,
166:             '#(</textarea|</pre|</script|^).*?(?=<textarea|<pre|<script|\z)#si',
167:             create_function('$m', '
168:                 return trim(preg_replace(\'#[ \\t\\r\\n]+#\', " ", $m[0]));
169:             '));
170:     }
171: 
172: 
173:     /**
174:      * Indents the HTML content from the left.
175:      * @param  string UTF-8 encoding or 8-bit
176:      * @param  int
177:      * @param  string
178:      * @return string
179:      */
180:     public static function indent($s, $level = 1, $chars = "\t")
181:     {
182:         if ($level >= 1) {
183:             $s = NStrings::replace($s, '#<(textarea|pre).*?</\\1#si', create_function('$m', '
184:                 return strtr($m[0], " \\t\\r\\n", "\\x1F\\x1E\\x1D\\x1A");
185:             '));
186:             $s = NStrings::indent($s, $level, $chars);
187:             $s = strtr($s, "\x1F\x1E\x1D\x1A", " \t\r\n");
188:         }
189:         return $s;
190:     }
191: 
192: 
193:     /**
194:      * Date/time formatting.
195:      * @param  string|int|DateTime
196:      * @param  string
197:      * @return string
198:      */
199:     public static function date($time, $format = NULL)
200:     {
201:         if ($time == NULL) { // intentionally ==
202:             return NULL;
203:         }
204: 
205:         if (!isset($format)) {
206:             $format = self::$dateFormat;
207:         }
208: 
209:         $time = NDateTime53::from($time);
210:         return NStrings::contains($format, '%')
211:             ? strftime($format, $time->format('U')) // formats according to locales
212:             : $time->format($format); // formats using date()
213:     }
214: 
215: 
216:     /**
217:      * Converts to human readable file size.
218:      * @param  int
219:      * @param  int
220:      * @return string
221:      */
222:     public static function bytes($bytes, $precision = 2)
223:     {
224:         $bytes = round($bytes);
225:         $units = array('B', 'kB', 'MB', 'GB', 'TB', 'PB');
226:         foreach ($units as $unit) {
227:             if (abs($bytes) < 1024 || $unit === end($units)) {
228:                 break;
229:             }
230:             $bytes = $bytes / 1024;
231:         }
232:         return round($bytes, $precision) . ' ' . $unit;
233:     }
234: 
235: 
236:     /**
237:      * Returns array of string length.
238:      * @param  mixed
239:      * @return int
240:      */
241:     public static function length($var)
242:     {
243:         return is_string($var) ? NStrings::length($var) : count($var);
244:     }
245: 
246: 
247:     /**
248:      * Performs a search and replace.
249:      * @param  string
250:      * @param  string
251:      * @param  string
252:      * @return string
253:      */
254:     public static function replace($subject, $search, $replacement = '')
255:     {
256:         return str_replace($search, $replacement, $subject);
257:     }
258: 
259: 
260:     /**
261:      * The data: URI generator.
262:      * @param  string
263:      * @param  string
264:      * @return string
265:      */
266:     public static function dataStream($data, $type = NULL)
267:     {
268:         if ($type === NULL) {
269:             $type = NMimeTypeDetector::fromString($data);
270:         }
271:         return 'data:' . ($type ? "$type;" : '') . 'base64,' . base64_encode($data);
272:     }
273: 
274: 
275:     /**
276:      * /dev/null.
277:      * @param  mixed
278:      * @return string
279:      */
280:     public static function null()
281:     {
282:         return '';
283:     }
284: 
285: 
286:     /**
287:      * @param  string
288:      * @return string
289:      */
290:     public static function nl2br($value)
291:     {
292:         return nl2br($value, NHtml::$xhtml);
293:     }
294: 
295: 
296:     /********************* Template tools ****************d*g**/
297: 
298: 
299:     /**
300:      * Removes unnecessary blocks of PHP code.
301:      * @param  string
302:      * @return string
303:      */
304:     public static function optimizePhp($source, $lineLength = 80, $existenceOfThisParameterSolvesDamnBugInPHP535 = NULL)
305:     {
306:         $res = $php = '';
307:         $lastChar = ';';
308:         $tokens = new ArrayIterator(token_get_all($source));
309:         foreach ($tokens as $key => $token) {
310:             if (is_array($token)) {
311:                 if ($token[0] === T_INLINE_HTML) {
312:                     $lastChar = '';
313:                     $res .= $token[1];
314: 
315:                 } elseif ($token[0] === T_CLOSE_TAG) {
316:                     $next = isset($tokens[$key + 1]) ? $tokens[$key + 1] : NULL;
317:                     if (substr($res, -1) !== '<' && preg_match('#^<\?php\s*\z#', $php)) {
318:                         $php = ''; // removes empty (?php ?), but retains ((?php ?)?php
319: 
320:                     } elseif (is_array($next) && $next[0] === T_OPEN_TAG) { // remove ?)(?php
321:                         if (!strspn($lastChar, ';{}:/')) {
322:                             $php .= $lastChar = ';';
323:                         }
324:                         if (substr($next[1], -1) === "\n") {
325:                             $php .= "\n";
326:                         }
327:                         $tokens->next();
328: 
329:                     } elseif ($next) {
330:                         $res .= preg_replace('#;?(\s)*\z#', '$1', $php) . $token[1]; // remove last semicolon before ?)
331:                         if (strlen($res) - strrpos($res, "\n") > $lineLength
332:                             && (!is_array($next) || strpos($next[1], "\n") === FALSE)
333:                         ) {
334:                             $res .= "\n";
335:                         }
336:                         $php = '';
337: 
338:                     } else { // remove last ?)
339:                         if (!strspn($lastChar, '};')) {
340:                             $php .= ';';
341:                         }
342:                     }
343: 
344:                 } elseif ($token[0] === T_ELSE || $token[0] === T_ELSEIF) {
345:                     if ($tokens[$key + 1] === ':' && $lastChar === '}') {
346:                         $php .= ';'; // semicolon needed in if(): ... if() ... else:
347:                     }
348:                     $lastChar = '';
349:                     $php .= $token[1];
350: 
351:                 } else {
352:                     if (!in_array($token[0], array(T_WHITESPACE, T_COMMENT, T_DOC_COMMENT, T_OPEN_TAG), TRUE)) {
353:                         $lastChar = '';
354:                     }
355:                     $php .= $token[1];
356:                 }
357:             } else {
358:                 $php .= $lastChar = $token;
359:             }
360:         }
361:         return $res . $php;
362:     }
363: 
364: }
365: 
Nette Framework 2.0.18 (for PHP 5.2, prefixed) API documentation generated by ApiGen 2.8.0