~ubuntu-branches/debian/experimental/php-nette/experimental

« back to all changes in this revision

Viewing changes to Nette-2.0.13/Nette/Templating/Helpers.php

  • Committer: Package Import Robot
  • Author(s): David Prévot
  • Date: 2013-11-30 08:47:54 UTC
  • mfrom: (1.1.1)
  • Revision ID: package-import@ubuntu.com-20131130084754-4udf1xsu9085tnfc
Tags: 2.1.0~rc-1
* New upstream branch
* Update copyright

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
<?php
2
 
 
3
 
/**
4
 
 * This file is part of the Nette Framework (http://nette.org)
5
 
 *
6
 
 * Copyright (c) 2004 David Grudl (http://davidgrudl.com)
7
 
 *
8
 
 * For the full copyright and license information, please view
9
 
 * the file license.txt that was distributed with this source code.
10
 
 */
11
 
 
12
 
namespace Nette\Templating;
13
 
 
14
 
use Nette,
15
 
        Nette\Utils\Strings,
16
 
        Nette\Forms\Form,
17
 
        Nette\Utils\Html;
18
 
 
19
 
 
20
 
/**
21
 
 * Template helpers.
22
 
 *
23
 
 * @author     David Grudl
24
 
 */
25
 
final class Helpers
26
 
{
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',
47
 
        );
48
 
 
49
 
        /** @var string default date format */
50
 
        public static $dateFormat = '%x';
51
 
 
52
 
 
53
 
        /**
54
 
         * Try to load the requested helper.
55
 
         * @param  string  helper name
56
 
         * @return callable
57
 
         */
58
 
        public static function loader($helper)
59
 
        {
60
 
                if (method_exists(__CLASS__, $helper)) {
61
 
                        return new Nette\Callback(__CLASS__, $helper);
62
 
                } elseif (isset(self::$helpers[$helper])) {
63
 
                        return self::$helpers[$helper];
64
 
                }
65
 
        }
66
 
 
67
 
 
68
 
        /**
69
 
         * Escapes string for use inside HTML template.
70
 
         * @param  mixed  UTF-8 encoding
71
 
         * @param  int    optional attribute quotes
72
 
         * @return string
73
 
         */
74
 
        public static function escapeHtml($s, $quotes = ENT_QUOTES)
75
 
        {
76
 
                if (is_object($s) && ($s instanceof ITemplate || $s instanceof Html || $s instanceof Form)) {
77
 
                        return $s->__toString(TRUE);
78
 
                }
79
 
                return htmlSpecialChars($s, $quotes);
80
 
        }
81
 
 
82
 
 
83
 
        /**
84
 
         * Escapes string for use inside HTML comments.
85
 
         * @param  string  UTF-8 encoding
86
 
         * @return string
87
 
         */
88
 
        public static function escapeHtmlComment($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 Html || $s instanceof Form)) {
128
 
                        $s = $s->__toString(TRUE);
129
 
                }
130
 
                return str_replace(array(']]>', '<!'), array(']]\x3E', '\x3C!'), Nette\Utils\Json::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
 
         * Replaces all repeated white spaces with a single space.
148
 
         * @param  string UTF-8 encoding or 8-bit
149
 
         * @return string
150
 
         */
151
 
        public static function strip($s)
152
 
        {
153
 
                return Strings::replace(
154
 
                        $s,
155
 
                        '#(</textarea|</pre|</script|^).*?(?=<textarea|<pre|<script|\z)#si',
156
 
                        function($m) {
157
 
                                return trim(preg_replace('#[ \t\r\n]+#', " ", $m[0]));
158
 
                        });
159
 
        }
160
 
 
161
 
 
162
 
        /**
163
 
         * Indents the HTML content from the left.
164
 
         * @param  string UTF-8 encoding or 8-bit
165
 
         * @param  int
166
 
         * @param  string
167
 
         * @return string
168
 
         */
169
 
        public static function indent($s, $level = 1, $chars = "\t")
170
 
        {
171
 
                if ($level >= 1) {
172
 
                        $s = Strings::replace($s, '#<(textarea|pre).*?</\\1#si', function($m) {
173
 
                                return strtr($m[0], " \t\r\n", "\x1F\x1E\x1D\x1A");
174
 
                        });
175
 
                        $s = Strings::indent($s, $level, $chars);
176
 
                        $s = strtr($s, "\x1F\x1E\x1D\x1A", " \t\r\n");
177
 
                }
178
 
                return $s;
179
 
        }
180
 
 
181
 
 
182
 
        /**
183
 
         * Date/time formatting.
184
 
         * @param  string|int|DateTime
185
 
         * @param  string
186
 
         * @return string
187
 
         */
188
 
        public static function date($time, $format = NULL)
189
 
        {
190
 
                if ($time == NULL) { // intentionally ==
191
 
                        return NULL;
192
 
                }
193
 
 
194
 
                if (!isset($format)) {
195
 
                        $format = self::$dateFormat;
196
 
                }
197
 
 
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()
202
 
        }
203
 
 
204
 
 
205
 
        /**
206
 
         * Converts to human readable file size.
207
 
         * @param  int
208
 
         * @param  int
209
 
         * @return string
210
 
         */
211
 
        public static function bytes($bytes, $precision = 2)
212
 
        {
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)) {
217
 
                                break;
218
 
                        }
219
 
                        $bytes = $bytes / 1024;
220
 
                }
221
 
                return round($bytes, $precision) . ' ' . $unit;
222
 
        }
223
 
 
224
 
 
225
 
        /**
226
 
         * Returns array of string length.
227
 
         * @param  mixed
228
 
         * @return int
229
 
         */
230
 
        public static function length($var)
231
 
        {
232
 
                return is_string($var) ? Strings::length($var) : count($var);
233
 
        }
234
 
 
235
 
 
236
 
        /**
237
 
         * Performs a search and replace.
238
 
         * @param  string
239
 
         * @param  string
240
 
         * @param  string
241
 
         * @return string
242
 
         */
243
 
        public static function replace($subject, $search, $replacement = '')
244
 
        {
245
 
                return str_replace($search, $replacement, $subject);
246
 
        }
247
 
 
248
 
 
249
 
        /**
250
 
         * The data: URI generator.
251
 
         * @param  string
252
 
         * @param  string
253
 
         * @return string
254
 
         */
255
 
        public static function dataStream($data, $type = NULL)
256
 
        {
257
 
                if ($type === NULL) {
258
 
                        $type = Nette\Utils\MimeTypeDetector::fromString($data);
259
 
                }
260
 
                return 'data:' . ($type ? "$type;" : '') . 'base64,' . base64_encode($data);
261
 
        }
262
 
 
263
 
 
264
 
        /**
265
 
         * /dev/null.
266
 
         * @param  mixed
267
 
         * @return string
268
 
         */
269
 
        public static function null($value)
270
 
        {
271
 
                return '';
272
 
        }
273
 
 
274
 
 
275
 
        /**
276
 
         * @param  string
277
 
         * @return string
278
 
         */
279
 
        public static function nl2br($value)
280
 
        {
281
 
                return nl2br($value, Html::$xhtml);
282
 
        }
283
 
 
284
 
 
285
 
        /********************* Template tools ****************d*g**/
286
 
 
287
 
 
288
 
        /**
289
 
         * Removes unnecessary blocks of PHP code.
290
 
         * @param  string
291
 
         * @return string
292
 
         */
293
 
        public static function optimizePhp($source, $lineLength = 80, $existenceOfThisParameterSolvesDamnBugInPHP535 = NULL)
294
 
        {
295
 
                $res = $php = '';
296
 
                $lastChar = ';';
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) {
301
 
                                        $lastChar = '';
302
 
                                        $res .= $token[1];
303
 
 
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
308
 
 
309
 
                                        } elseif (is_array($next) && $next[0] === T_OPEN_TAG) { // remove ?)(?php
310
 
                                                if (!strspn($lastChar, ';{}:/')) {
311
 
                                                        $php .= $lastChar = ';';
312
 
                                                }
313
 
                                                if (substr($next[1], -1) === "\n") {
314
 
                                                        $php .= "\n";
315
 
                                                }
316
 
                                                $tokens->next();
317
 
 
318
 
                                        } elseif ($next) {
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)
322
 
                                                ) {
323
 
                                                        $res .= "\n";
324
 
                                                }
325
 
                                                $php = '';
326
 
 
327
 
                                        } else { // remove last ?)
328
 
                                                if (!strspn($lastChar, '};')) {
329
 
                                                        $php .= ';';
330
 
                                                }
331
 
                                        }
332
 
 
333
 
                                } elseif ($token[0] === T_ELSE || $token[0] === T_ELSEIF) {
334
 
                                        if ($tokens[$key + 1] === ':' && $lastChar === '}') {
335
 
                                                $php .= ';'; // semicolon needed in if(): ... if() ... else:
336
 
                                        }
337
 
                                        $lastChar = '';
338
 
                                        $php .= $token[1];
339
 
 
340
 
                                } else {
341
 
                                        if (!in_array($token[0], array(T_WHITESPACE, T_COMMENT, T_DOC_COMMENT, T_OPEN_TAG))) {
342
 
                                                $lastChar = '';
343
 
                                        }
344
 
                                        $php .= $token[1];
345
 
                                }
346
 
                        } else {
347
 
                                $php .= $lastChar = $token;
348
 
                        }
349
 
                }
350
 
                return $res . $php;
351
 
        }
352
 
 
353
 
}