Overview

Namespaces

  • Budovy
  • Kdyby
    • BootstrapFormRenderer
      • DI
      • Latte
  • 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
  • Nextras
    • Datagrid
  • None
  • PHP
  • Tester
    • CodeCoverage
    • Runner
      • Output
  • Vodacek
    • Forms
      • Controls
  • WebLoader
    • Filter
    • Nette

Classes

  • FileTemplate
  • Helpers
  • Template

Interfaces

  • IFileTemplate
  • ITemplate

Exceptions

  • FilterException
  • Overview
  • Namespace
  • Class
  • Tree
  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 (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:      * Escapes string for use inside HTML comments.
 82:      * @param  string  UTF-8 encoding
 83:      * @return string
 84:      */
 85:     public static function escapeHtmlComment($s)
 86:     {
 87:         return ' ' . str_replace('-', '- ', $s); // dash is very problematic character in comments
 88:     }
 89: 
 90: 
 91:     /**
 92:      * Escapes string for use inside XML 1.0 template.
 93:      * @param  string UTF-8 encoding
 94:      * @return string
 95:      */
 96:     public static function escapeXML($s)
 97:     {
 98:         // XML 1.0: \x09 \x0A \x0D and C1 allowed directly, C0 forbidden
 99:         // XML 1.1: \x00 forbidden directly and as a character reference,
100:         //   \x09 \x0A \x0D \x85 allowed directly, C0, C1 and \x7F allowed as character references
101:         return htmlSpecialChars(preg_replace('#[\x00-\x08\x0B\x0C\x0E-\x1F]+#', '', $s), ENT_QUOTES);
102:     }
103: 
104: 
105:     /**
106:      * Escapes string for use inside CSS template.
107:      * @param  string UTF-8 encoding
108:      * @return string
109:      */
110:     public static function escapeCss($s)
111:     {
112:         // http://www.w3.org/TR/2006/WD-CSS21-20060411/syndata.html#q6
113:         return addcslashes($s, "\x00..\x1F!\"#$%&'()*+,./:;<=>?@[\\]^`{|}~");
114:     }
115: 
116: 
117:     /**
118:      * Escapes variables for use inside <script>.
119:      * @param  mixed  UTF-8 encoding
120:      * @return string
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:      * Escapes string for use inside iCal template.
133:      * @param  mixed  UTF-8 encoding
134:      * @return string
135:      */
136:     public static function escapeICal($s)
137:     {
138:         // http://www.ietf.org/rfc/rfc5545.txt
139:         return addcslashes(preg_replace('#[\x00-\x08\x0B\x0C-\x1F]+#', '', $s), "\";\\,:\n");
140:     }
141: 
142: 
143:     /**
144:      * Sanitizes string for use inside href attribute.
145:      * @param  string
146:      * @return string
147:      */
148:     public static function safeUrl($s)
149:     {
150:         return preg_match('~^(?:(?:https?|ftp)://[^@]+(?:/.*)?|mailto:.+|[/?#].*|[^:]+)\z~i', $s) ? $s : '';
151:     }
152: 
153: 
154:     /**
155:      * Replaces all repeated white spaces with a single space.
156:      * @param  string UTF-8 encoding or 8-bit
157:      * @return string
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:      * Indents the HTML content from the left.
172:      * @param  string UTF-8 encoding or 8-bit
173:      * @param  int
174:      * @param  string
175:      * @return string
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:      * Date/time formatting.
192:      * @param  string|int|DateTime|DateInterval
193:      * @param  string
194:      * @return string
195:      */
196:     public static function date($time, $format = NULL)
197:     {
198:         if ($time == NULL) { // intentionally ==
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')) // formats according to locales
213:             : $time->format($format); // formats using date()
214:     }
215: 
216: 
217:     /**
218:      * Date/time modification.
219:      * @param  string|int|DateTime
220:      * @param  string|int
221:      * @param  string
222:      * @return Nette\DateTime
223:      */
224:     public static function modifyDate($time, $delta, $unit = NULL)
225:     {
226:         return $time == NULL // intentionally ==
227:             ? NULL
228:             : Nette\DateTime::from($time)->modify($delta . $unit);
229:     }
230: 
231: 
232:     /**
233:      * Converts to human readable file size.
234:      * @param  int
235:      * @param  int
236:      * @return string
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:      * Returns array of string length.
254:      * @param  mixed
255:      * @return int
256:      */
257:     public static function length($var)
258:     {
259:         return is_string($var) ? Strings::length($var) : count($var);
260:     }
261: 
262: 
263:     /**
264:      * Performs a search and replace.
265:      * @param  string
266:      * @param  string
267:      * @param  string
268:      * @return string
269:      */
270:     public static function replace($subject, $search, $replacement = '')
271:     {
272:         return str_replace($search, $replacement, $subject);
273:     }
274: 
275: 
276:     /**
277:      * The data: URI generator.
278:      * @param  string
279:      * @param  string
280:      * @return string
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:      * /dev/null.
293:      * @param  mixed
294:      * @return string
295:      */
296:     public static function null()
297:     {
298:         return '';
299:     }
300: 
301: 
302:     /**
303:      * @param  string
304:      * @return string
305:      */
306:     public static function nl2br($value)
307:     {
308:         return nl2br($value, Html::$xhtml);
309:     }
310: 
311: 
312:     /********************* Template tools ****************d*g**/
313: 
314: 
315:     /**
316:      * Removes unnecessary blocks of PHP code.
317:      * @param  string
318:      * @return string
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 = ''; // removes empty (?php ?), but retains ((?php ?)?php
335: 
336:                     } elseif (is_array($next) && $next[0] === T_OPEN_TAG) { // remove ?)(?php
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]; // remove last semicolon before ?)
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 { // remove last ?)
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 .= ';'; // semicolon needed in if(): ... if() ... else:
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: 
API documentation generated by ApiGen 2.8.0