4
* This file is part of the Nette Framework (http://nette.org)
6
* Copyright (c) 2004 David Grudl (http://davidgrudl.com)
8
* For the full copyright and license information, please view
9
* the file license.txt that was distributed with this source code.
12
namespace Nette\Templating;
27
private static $helpers = array(
28
'normalize' => 'Nette\Utils\Strings::normalize',
29
'toascii' => 'Nette\Utils\Strings::toAscii',
30
'webalize' => 'Nette\Utils\Strings::webalize',
31
'truncate' => 'Nette\Utils\Strings::truncate',
32
'lower' => 'Nette\Utils\Strings::lower',
33
'upper' => 'Nette\Utils\Strings::upper',
34
'firstupper' => 'Nette\Utils\Strings::firstUpper',
35
'capitalize' => 'Nette\Utils\Strings::capitalize',
36
'trim' => 'Nette\Utils\Strings::trim',
37
'padleft' => 'Nette\Utils\Strings::padLeft',
38
'padright' => 'Nette\Utils\Strings::padRight',
39
'reverse' => 'Nette\Utils\Strings::reverse',
40
'replacere' => 'Nette\Utils\Strings::replace',
41
'url' => 'rawurlencode',
42
'striptags' => 'strip_tags',
43
'substr' => 'Nette\Utils\Strings::substring',
44
'repeat' => 'str_repeat',
45
'implode' => 'implode',
46
'number' => 'number_format',
49
/** @var string default date format */
50
public static $dateFormat = '%x';
54
* Try to load the requested helper.
55
* @param string helper name
58
public static function loader($helper)
60
if (method_exists(__CLASS__, $helper)) {
61
return new Nette\Callback(__CLASS__, $helper);
62
} elseif (isset(self::$helpers[$helper])) {
63
return self::$helpers[$helper];
69
* Escapes string for use inside HTML template.
70
* @param mixed UTF-8 encoding
71
* @param int optional attribute quotes
74
public static function escapeHtml($s, $quotes = ENT_QUOTES)
76
if (is_object($s) && ($s instanceof ITemplate || $s instanceof Html || $s instanceof Form)) {
77
return $s->__toString(TRUE);
79
return htmlSpecialChars($s, $quotes);
84
* Escapes string for use inside HTML comments.
85
* @param string UTF-8 encoding
88
public static function escapeHtmlComment($s)
90
return ' ' . str_replace('-', '- ', $s); // dash is very problematic character in comments
95
* Escapes string for use inside XML 1.0 template.
96
* @param string UTF-8 encoding
99
public static function escapeXML($s)
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);
109
* Escapes string for use inside CSS template.
110
* @param string UTF-8 encoding
113
public static function escapeCss($s)
115
// http://www.w3.org/TR/2006/WD-CSS21-20060411/syndata.html#q6
116
return addcslashes($s, "\x00..\x1F!\"#$%&'()*+,./:;<=>?@[\\]^`{|}~");
121
* Escapes variables for use inside <script>.
122
* @param mixed UTF-8 encoding
125
public static function escapeJs($s)
127
if (is_object($s) && ($s instanceof ITemplate || $s instanceof Html || $s instanceof Form)) {
128
$s = $s->__toString(TRUE);
130
return str_replace(array(']]>', '<!'), array(']]\x3E', '\x3C!'), Nette\Utils\Json::encode($s));
135
* Escapes string for use inside iCal template.
136
* @param mixed UTF-8 encoding
139
public static function escapeICal($s)
141
// http://www.ietf.org/rfc/rfc5545.txt
142
return addcslashes(preg_replace('#[\x00-\x08\x0B\x0C-\x1F]+#', '', $s), "\";\\,:\n");
147
* Replaces all repeated white spaces with a single space.
148
* @param string UTF-8 encoding or 8-bit
151
public static function strip($s)
153
return Strings::replace(
155
'#(</textarea|</pre|</script|^).*?(?=<textarea|<pre|<script|\z)#si',
157
return trim(preg_replace('#[ \t\r\n]+#', " ", $m[0]));
163
* Indents the HTML content from the left.
164
* @param string UTF-8 encoding or 8-bit
169
public static function indent($s, $level = 1, $chars = "\t")
172
$s = Strings::replace($s, '#<(textarea|pre).*?</\\1#si', function($m) {
173
return strtr($m[0], " \t\r\n", "\x1F\x1E\x1D\x1A");
175
$s = Strings::indent($s, $level, $chars);
176
$s = strtr($s, "\x1F\x1E\x1D\x1A", " \t\r\n");
183
* Date/time formatting.
184
* @param string|int|DateTime
188
public static function date($time, $format = NULL)
190
if ($time == NULL) { // intentionally ==
194
if (!isset($format)) {
195
$format = self::$dateFormat;
198
$time = Nette\DateTime::from($time);
199
return Strings::contains($format, '%')
200
? strftime($format, $time->format('U')) // formats according to locales
201
: $time->format($format); // formats using date()
206
* Converts to human readable file size.
211
public static function bytes($bytes, $precision = 2)
213
$bytes = round($bytes);
214
$units = array('B', 'kB', 'MB', 'GB', 'TB', 'PB');
215
foreach ($units as $unit) {
216
if (abs($bytes) < 1024 || $unit === end($units)) {
219
$bytes = $bytes / 1024;
221
return round($bytes, $precision) . ' ' . $unit;
226
* Returns array of string length.
230
public static function length($var)
232
return is_string($var) ? Strings::length($var) : count($var);
237
* Performs a search and replace.
243
public static function replace($subject, $search, $replacement = '')
245
return str_replace($search, $replacement, $subject);
250
* The data: URI generator.
255
public static function dataStream($data, $type = NULL)
257
if ($type === NULL) {
258
$type = Nette\Utils\MimeTypeDetector::fromString($data);
260
return 'data:' . ($type ? "$type;" : '') . 'base64,' . base64_encode($data);
269
public static function null($value)
279
public static function nl2br($value)
281
return nl2br($value, Html::$xhtml);
285
/********************* Template tools ****************d*g**/
289
* Removes unnecessary blocks of PHP code.
293
public static function optimizePhp($source, $lineLength = 80, $existenceOfThisParameterSolvesDamnBugInPHP535 = NULL)
297
$tokens = new \ArrayIterator(token_get_all($source));
298
foreach ($tokens as $key => $token) {
299
if (is_array($token)) {
300
if ($token[0] === T_INLINE_HTML) {
304
} elseif ($token[0] === T_CLOSE_TAG) {
305
$next = isset($tokens[$key + 1]) ? $tokens[$key + 1] : NULL;
306
if (substr($res, -1) !== '<' && preg_match('#^<\?php\s*\z#', $php)) {
307
$php = ''; // removes empty (?php ?), but retains ((?php ?)?php
309
} elseif (is_array($next) && $next[0] === T_OPEN_TAG) { // remove ?)(?php
310
if (!strspn($lastChar, ';{}:/')) {
311
$php .= $lastChar = ';';
313
if (substr($next[1], -1) === "\n") {
319
$res .= preg_replace('#;?(\s)*\z#', '$1', $php) . $token[1]; // remove last semicolon before ?)
320
if (strlen($res) - strrpos($res, "\n") > $lineLength
321
&& (!is_array($next) || strpos($next[1], "\n") === FALSE)
327
} else { // remove last ?)
328
if (!strspn($lastChar, '};')) {
333
} elseif ($token[0] === T_ELSE || $token[0] === T_ELSEIF) {
334
if ($tokens[$key + 1] === ':' && $lastChar === '}') {
335
$php .= ';'; // semicolon needed in if(): ... if() ... else:
341
if (!in_array($token[0], array(T_WHITESPACE, T_COMMENT, T_DOC_COMMENT, T_OPEN_TAG))) {
347
$php .= $lastChar = $token;