Namespaces

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

Classes

  • FileTemplate
  • Helpers
  • Template

Interfaces

  • IFileTemplate
  • ITemplate

Exceptions

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