Initial Kohana install
[speedfreak] / Server / system / helpers / html.php
1 <?php defined('SYSPATH') OR die('No direct access allowed.');
2 /**
3  * HTML helper class.
4  *
5  * $Id: html.php 4376 2009-06-01 11:40:39Z samsoir $
6  *
7  * @package    Core
8  * @author     Kohana Team
9  * @copyright  (c) 2007-2008 Kohana Team
10  * @license    http://kohanaphp.com/license.html
11  */
12 class html_Core {
13
14         // Enable or disable automatic setting of target="_blank"
15         public static $windowed_urls = FALSE;
16
17         /**
18          * Convert special characters to HTML entities
19          *
20          * @param   string   string to convert
21          * @param   boolean  encode existing entities
22          * @return  string
23          */
24         public static function specialchars($str, $double_encode = TRUE)
25         {
26                 // Force the string to be a string
27                 $str = (string) $str;
28
29                 // Do encode existing HTML entities (default)
30                 if ($double_encode === TRUE)
31                 {
32                         $str = htmlspecialchars($str, ENT_QUOTES, 'UTF-8');
33                 }
34                 else
35                 {
36                         // Do not encode existing HTML entities
37                         // From PHP 5.2.3 this functionality is built-in, otherwise use a regex
38                         if (version_compare(PHP_VERSION, '5.2.3', '>='))
39                         {
40                                 $str = htmlspecialchars($str, ENT_QUOTES, 'UTF-8', FALSE);
41                         }
42                         else
43                         {
44                                 $str = preg_replace('/&(?!(?:#\d++|[a-z]++);)/ui', '&amp;', $str);
45                                 $str = str_replace(array('<', '>', '\'', '"'), array('&lt;', '&gt;', '&#39;', '&quot;'), $str);
46                         }
47                 }
48
49                 return $str;
50         }
51
52         /**
53          * Perform a html::specialchars() with additional URL specific encoding.
54          *  
55          * @param   string   string to convert
56          * @param   boolean  encode existing entities
57          * @return  string
58          */
59         public static function specialurlencode($str, $double_encode = TRUE)
60         {
61                 return str_replace(' ', '%20', html::specialchars($str, $double_encode));
62         }
63         
64         /**
65          * Create HTML link anchors.
66          *
67          * @param   string  URL or URI string
68          * @param   string  link text
69          * @param   array   HTML anchor attributes
70          * @param   string  non-default protocol, eg: https
71          * @param   boolean option to escape the title that is output
72          * @return  string
73          */
74         public static function anchor($uri, $title = NULL, $attributes = NULL, $protocol = NULL, $escape_title = FALSE)
75         {
76                 if ($uri === '')
77                 {
78                         $site_url = url::base(FALSE);
79                 }
80                 elseif (strpos($uri, '#') === 0)
81                 {
82                         // This is an id target link, not a URL
83                         $site_url = $uri;
84                 }
85                 elseif (strpos($uri, '://') === FALSE)
86                 {
87                         $site_url = url::site($uri, $protocol);
88                 }
89                 else
90                 {
91                         if (html::$windowed_urls === TRUE AND empty($attributes['target']))
92                         {
93                                 $attributes['target'] = '_blank';
94                         }
95
96                         $site_url = $uri;
97                 }
98
99                 return
100                 // Parsed URL
101                 '<a href="'.html::specialurlencode($site_url, FALSE).'"'
102                 // Attributes empty? Use an empty string
103                 .(is_array($attributes) ? html::attributes($attributes) : '').'>'
104                 // Title empty? Use the parsed URL
105                 .($escape_title ? html::specialchars((($title === NULL) ? $site_url : $title), FALSE) : (($title === NULL) ? $site_url : $title)).'</a>';
106         }
107
108         /**
109          * Creates an HTML anchor to a file.
110          *
111          * @param   string  name of file to link to
112          * @param   string  link text
113          * @param   array   HTML anchor attributes
114          * @param   string  non-default protocol, eg: ftp
115          * @return  string
116          */
117         public static function file_anchor($file, $title = NULL, $attributes = NULL, $protocol = NULL)
118         {
119                 return
120                 // Base URL + URI = full URL
121                 '<a href="'.html::specialurlencode(url::base(FALSE, $protocol).$file, FALSE).'"'
122                 // Attributes empty? Use an empty string
123                 .(is_array($attributes) ? html::attributes($attributes) : '').'>'
124                 // Title empty? Use the filename part of the URI
125                 .(($title === NULL) ? end(explode('/', $file)) : $title) .'</a>';
126         }
127
128         /**
129          * Similar to anchor, but with the protocol parameter first.
130          *
131          * @param   string  link protocol
132          * @param   string  URI or URL to link to
133          * @param   string  link text
134          * @param   array   HTML anchor attributes
135          * @return  string
136          */
137         public static function panchor($protocol, $uri, $title = NULL, $attributes = FALSE)
138         {
139                 return html::anchor($uri, $title, $attributes, $protocol);
140         }
141
142         /**
143          * Create an array of anchors from an array of link/title pairs.
144          *
145          * @param   array  link/title pairs
146          * @return  array
147          */
148         public static function anchor_array(array $array)
149         {
150                 $anchors = array();
151                 foreach ($array as $link => $title)
152                 {
153                         // Create list of anchors
154                         $anchors[] = html::anchor($link, $title);
155                 }
156                 return $anchors;
157         }
158
159         /**
160          * Generates an obfuscated version of an email address.
161          *
162          * @param   string  email address
163          * @return  string
164          */
165         public static function email($email)
166         {
167                 $safe = '';
168                 foreach (str_split($email) as $letter)
169                 {
170                         switch (($letter === '@') ? rand(1, 2) : rand(1, 3))
171                         {
172                                 // HTML entity code
173                                 case 1: $safe .= '&#'.ord($letter).';'; break;
174                                 // Hex character code
175                                 case 2: $safe .= '&#x'.dechex(ord($letter)).';'; break;
176                                 // Raw (no) encoding
177                                 case 3: $safe .= $letter;
178                         }
179                 }
180
181                 return $safe;
182         }
183
184         /**
185          * Creates an email anchor.
186          *
187          * @param   string  email address to send to
188          * @param   string  link text
189          * @param   array   HTML anchor attributes
190          * @return  string
191          */
192         public static function mailto($email, $title = NULL, $attributes = NULL)
193         {
194                 if (empty($email))
195                         return $title;
196
197                 // Remove the subject or other parameters that do not need to be encoded
198                 if (strpos($email, '?') !== FALSE)
199                 {
200                         // Extract the parameters from the email address
201                         list ($email, $params) = explode('?', $email, 2);
202
203                         // Make the params into a query string, replacing spaces
204                         $params = '?'.str_replace(' ', '%20', $params);
205                 }
206                 else
207                 {
208                         // No parameters
209                         $params = '';
210                 }
211
212                 // Obfuscate email address
213                 $safe = html::email($email);
214
215                 // Title defaults to the encoded email address
216                 empty($title) and $title = $safe;
217
218                 // Parse attributes
219                 empty($attributes) or $attributes = html::attributes($attributes);
220
221                 // Encoded start of the href="" is a static encoded version of 'mailto:'
222                 return '<a href="&#109;&#097;&#105;&#108;&#116;&#111;&#058;'.$safe.$params.'"'.$attributes.'>'.$title.'</a>';
223         }
224
225         /**
226          * Generate a "breadcrumb" list of anchors representing the URI.
227          *
228          * @param   array   segments to use as breadcrumbs, defaults to using Router::$segments
229          * @return  string
230          */
231         public static function breadcrumb($segments = NULL)
232         {
233                 empty($segments) and $segments = Router::$segments;
234
235                 $array = array();
236                 while ($segment = array_pop($segments))
237                 {
238                         $array[] = html::anchor
239                         (
240                                 // Complete URI for the URL
241                                 implode('/', $segments).'/'.$segment,
242                                 // Title for the current segment
243                                 ucwords(inflector::humanize($segment))
244                         );
245                 }
246
247                 // Retrun the array of all the segments
248                 return array_reverse($array);
249         }
250
251         /**
252          * Creates a meta tag.
253          *
254          * @param   string|array   tag name, or an array of tags
255          * @param   string         tag "content" value
256          * @return  string
257          */
258         public static function meta($tag, $value = NULL)
259         {
260                 if (is_array($tag))
261                 {
262                         $tags = array();
263                         foreach ($tag as $t => $v)
264                         {
265                                 // Build each tag and add it to the array
266                                 $tags[] = html::meta($t, $v);
267                         }
268
269                         // Return all of the tags as a string
270                         return implode("\n", $tags);
271                 }
272
273                 // Set the meta attribute value
274                 $attr = in_array(strtolower($tag), Kohana::config('http.meta_equiv')) ? 'http-equiv' : 'name';
275
276                 return '<meta '.$attr.'="'.$tag.'" content="'.$value.'" />';
277         }
278
279         /**
280          * Creates a stylesheet link.
281          *
282          * @param   string|array  filename, or array of filenames to match to array of medias
283          * @param   string|array  media type of stylesheet, or array to match filenames
284          * @param   boolean       include the index_page in the link
285          * @return  string
286          */
287         public static function stylesheet($style, $media = FALSE, $index = FALSE)
288         {
289                 return html::link($style, 'stylesheet', 'text/css', '.css', $media, $index);
290         }
291
292         /**
293          * Creates a link tag.
294          *
295          * @param   string|array  filename
296          * @param   string|array  relationship
297          * @param   string|array  mimetype
298          * @param   string        specifies suffix of the file
299          * @param   string|array  specifies on what device the document will be displayed
300          * @param   boolean       include the index_page in the link
301          * @return  string
302          */
303         public static function link($href, $rel, $type, $suffix = FALSE, $media = FALSE, $index = FALSE)
304         {
305                 $compiled = '';
306
307                 if (is_array($href))
308                 {
309                         foreach ($href as $_href)
310                         {
311                                 $_rel   = is_array($rel) ? array_shift($rel) : $rel;
312                                 $_type  = is_array($type) ? array_shift($type) : $type;
313                                 $_media = is_array($media) ? array_shift($media) : $media;
314
315                                 $compiled .= html::link($_href, $_rel, $_type, $suffix, $_media, $index);
316                         }
317                 }
318                 else
319                 {
320                         if (strpos($href, '://') === FALSE)
321                         {
322                                 // Make the URL absolute
323                                 $href = url::base($index).$href;
324                         }
325
326                         $length = strlen($suffix);
327
328                         if ( $length > 0 AND substr_compare($href, $suffix, -$length, $length, FALSE) !== 0)
329                         {
330                                 // Add the defined suffix
331                                 $href .= $suffix;
332                         }
333
334                         $attr = array
335                         (
336                                 'rel' => $rel,
337                                 'type' => $type,
338                                 'href' => $href,
339                         );
340
341                         if ( ! empty($media))
342                         {
343                                 // Add the media type to the attributes
344                                 $attr['media'] = $media;
345                         }
346
347                         $compiled = '<link'.html::attributes($attr).' />';
348                 }
349
350                 return $compiled."\n";
351         }
352
353         /**
354          * Creates a script link.
355          *
356          * @param   string|array  filename
357          * @param   boolean       include the index_page in the link
358          * @return  string
359          */
360         public static function script($script, $index = FALSE)
361         {
362                 $compiled = '';
363
364                 if (is_array($script))
365                 {
366                         foreach ($script as $name)
367                         {
368                                 $compiled .= html::script($name, $index);
369                         }
370                 }
371                 else
372                 {
373                         if (strpos($script, '://') === FALSE)
374                         {
375                                 // Add the suffix only when it's not already present
376                                 $script = url::base((bool) $index).$script;
377                         }
378
379                         if (substr_compare($script, '.js', -3, 3, FALSE) !== 0)
380                         {
381                                 // Add the javascript suffix
382                                 $script .= '.js';
383                         }
384
385                         $compiled = '<script type="text/javascript" src="'.$script.'"></script>';
386                 }
387
388                 return $compiled."\n";
389         }
390
391         /**
392          * Creates a image link.
393          *
394          * @param   string        image source, or an array of attributes
395          * @param   string|array  image alt attribute, or an array of attributes
396          * @param   boolean       include the index_page in the link
397          * @return  string
398          */
399         public static function image($src = NULL, $alt = NULL, $index = FALSE)
400         {
401                 // Create attribute list
402                 $attributes = is_array($src) ? $src : array('src' => $src);
403
404                 if (is_array($alt))
405                 {
406                         $attributes += $alt;
407                 }
408                 elseif ( ! empty($alt))
409                 {
410                         // Add alt to attributes
411                         $attributes['alt'] = $alt;
412                 }
413
414                 if (strpos($attributes['src'], '://') === FALSE)
415                 {
416                         // Make the src attribute into an absolute URL
417                         $attributes['src'] = url::base($index).$attributes['src'];
418                 }
419
420                 return '<img'.html::attributes($attributes).' />';
421         }
422
423         /**
424          * Compiles an array of HTML attributes into an attribute string.
425          *
426          * @param   string|array  array of attributes
427          * @return  string
428          */
429         public static function attributes($attrs)
430         {
431                 if (empty($attrs))
432                         return '';
433
434                 if (is_string($attrs))
435                         return ' '.$attrs;
436
437                 $compiled = '';
438                 foreach ($attrs as $key => $val)
439                 {
440                         $compiled .= ' '.$key.'="'.html::specialchars($val).'"';
441                 }
442
443                 return $compiled;
444         }
445
446 } // End html