Merge branch 'maint/7.0'
[ninja.git] / system / helpers / html.php
blob8732a52160ca01f37b4eb0c93ed1d3a4abf508a8
1 <?php defined('SYSPATH') OR die('No direct access allowed.');
2 /**
3 * HTML helper class.
5 * $Id: html.php 3917 2009-01-21 03:06:22Z zombor $
7 * @package Core
8 * @author Kohana Team
9 * @copyright (c) 2007-2008 Kohana Team
10 * @license http://kohanaphp.com/license.html
12 class html {
14 // Enable or disable automatic setting of target="_blank"
15 public static $windowed_urls = FALSE;
17 /**
18 * Convert special characters to HTML entities
20 * @param string string to convert
21 * @param boolean encode existing entities
22 * @return string
24 public static function specialchars($str, $double_encode = TRUE)
26 // Force the string to be a string
27 $str = (string) $str;
29 // Do encode existing HTML entities (default)
30 if ($double_encode === TRUE)
32 $str = htmlspecialchars($str, ENT_QUOTES, 'ISO-8859-15');
34 else
36 $str = htmlspecialchars($str, ENT_QUOTES, 'UTF-8', FALSE);
39 return $str;
42 /**
43 * Create HTML link anchors.
45 * @param string URL or URI string
46 * @param string link text
47 * @param array HTML anchor attributes
48 * @param string non-default protocol, eg: https
49 * @return string
51 public static function anchor($uri, $title = NULL, $attributes = NULL, $protocol = NULL)
53 if ($uri === '')
55 $site_url = url::base(FALSE);
57 elseif (strpos($uri, '://') === FALSE AND strpos($uri, '#') !== 0)
59 $site_url = url::site($uri, $protocol);
61 else
63 if (html::$windowed_urls === TRUE AND empty($attributes['target']))
65 $attributes['target'] = '_blank';
68 $site_url = $uri;
71 return
72 // Parsed URL
73 '<a href="'.html::specialchars($site_url, FALSE).'"'
74 // Attributes empty? Use an empty string
75 .(is_array($attributes) ? html::attributes($attributes) : '').'>'
76 // Title empty? Use the parsed URL
77 .(($title === NULL) ? $site_url : $title).'</a>';
80 /**
81 * Creates an HTML anchor to a file.
83 * @param string name of file to link to
84 * @param string link text
85 * @param array HTML anchor attributes
86 * @param string non-default protocol, eg: ftp
87 * @return string
89 public static function file_anchor($file, $title = NULL, $attributes = NULL, $protocol = NULL)
91 return
92 // Base URL + URI = full URL
93 '<a href="'.html::specialchars(url::base(FALSE, $protocol).$file, FALSE).'"'
94 // Attributes empty? Use an empty string
95 .(is_array($attributes) ? html::attributes($attributes) : '').'>'
96 // Title empty? Use the filename part of the URI
97 .(($title === NULL) ? end(explode('/', $file)) : $title) .'</a>';
101 * Similar to anchor, but with the protocol parameter first.
103 * @param string link protocol
104 * @param string URI or URL to link to
105 * @param string link text
106 * @param array HTML anchor attributes
107 * @return string
109 public static function panchor($protocol, $uri, $title = FALSE, $attributes = FALSE)
111 return html::anchor($uri, $title, $attributes, $protocol);
115 * Create an array of anchors from an array of link/title pairs.
117 * @param array link/title pairs
118 * @return array
120 public static function anchor_array(array $array)
122 $anchors = array();
123 foreach ($array as $link => $title)
125 // Create list of anchors
126 $anchors[] = html::anchor($link, $title);
128 return $anchors;
132 * Generates an obfuscated version of an email address.
134 * @param string email address
135 * @return string
137 public static function email($email)
139 $safe = '';
140 foreach (str_split($email) as $letter)
142 switch (($letter === '@') ? rand(1, 2) : rand(1, 3))
144 // HTML entity code
145 case 1: $safe .= '&#'.ord($letter).';'; break;
146 // Hex character code
147 case 2: $safe .= '&#x'.dechex(ord($letter)).';'; break;
148 // Raw (no) encoding
149 case 3: $safe .= $letter;
153 return $safe;
157 * Creates an email anchor.
159 * @param string email address to send to
160 * @param string link text
161 * @param array HTML anchor attributes
162 * @return string
164 public static function mailto($email, $title = NULL, $attributes = NULL)
166 if (empty($email))
167 return $title;
169 // Remove the subject or other parameters that do not need to be encoded
170 if (strpos($email, '?') !== FALSE)
172 // Extract the parameters from the email address
173 list ($email, $params) = explode('?', $email, 2);
175 // Make the params into a query string, replacing spaces
176 $params = '?'.str_replace(' ', '%20', $params);
178 else
180 // No parameters
181 $params = '';
184 // Obfuscate email address
185 $safe = html::email($email);
187 // Title defaults to the encoded email address
188 empty($title) and $title = $safe;
190 // Parse attributes
191 empty($attributes) or $attributes = html::attributes($attributes);
193 // Encoded start of the href="" is a static encoded version of 'mailto:'
194 return '<a href="&#109;&#097;&#105;&#108;&#116;&#111;&#058;'.$safe.$params.'"'.$attributes.'>'.$title.'</a>';
198 * Generate a "breadcrumb" list of anchors representing the URI.
200 * @param array segments to use as breadcrumbs, defaults to using Router::$segments
201 * @return string
203 public static function breadcrumb($segments = NULL)
205 empty($segments) and $segments = Router::$segments;
207 $array = array();
208 while ($segment = array_pop($segments))
210 $array[] = html::anchor
212 // Complete URI for the URL
213 implode('/', $segments).'/'.$segment,
214 // Title for the current segment
215 ucwords(inflector::humanize($segment))
219 // Retrun the array of all the segments
220 return array_reverse($array);
224 * Creates a meta tag.
226 * @param string|array tag name, or an array of tags
227 * @param string tag "content" value
228 * @return string
230 public static function meta($tag, $value = NULL)
232 if (is_array($tag))
234 $tags = array();
235 foreach ($tag as $t => $v)
237 // Build each tag and add it to the array
238 $tags[] = html::meta($t, $v);
241 // Return all of the tags as a string
242 return implode("\n", $tags);
245 // Set the meta attribute value
246 $attr = in_array(strtolower($tag), Kohana::config('http.meta_equiv')) ? 'http-equiv' : 'name';
248 return '<meta '.$attr.'="'.$tag.'" content="'.$value.'" />';
252 * Creates a stylesheet link.
254 * @param string|array filename, or array of filenames to match to array of medias
255 * @param string|array media type of stylesheet, or array to match filenames
256 * @param boolean include the index_page in the link
257 * @return string
259 public static function stylesheet($style, $media = FALSE, $index = FALSE)
261 if(pathinfo($style, PATHINFO_EXTENSION) !== 'css') {
262 $style .= '.css';
264 if(class_exists('ninja')) {
265 return html::link(ninja::add_version_to_uri($style), 'stylesheet', 'text/css', null, $media, $index);
267 return html::link($style, 'stylesheet', 'text/css', null, $media, $index);
271 * Creates a link tag.
273 * @param string|array filename
274 * @param string|array relationship
275 * @param string|array mimetype
276 * @param string specifies suffix of the file
277 * @param string|array specifies on what device the document will be displayed
278 * @param boolean include the index_page in the link
279 * @return string
281 public static function link($href, $rel, $type, $suffix = FALSE, $media = FALSE, $index = FALSE)
283 $compiled = '';
285 if (is_array($href))
287 foreach ($href as $_href)
289 $_rel = is_array($rel) ? array_shift($rel) : $rel;
290 $_type = is_array($type) ? array_shift($type) : $type;
291 $_media = is_array($media) ? array_shift($media) : $media;
293 $compiled .= html::link($_href, $_rel, $_type, $suffix, $_media, $index);
296 else
298 if (strpos($href, '://') === FALSE)
300 // Make the URL absolute
301 $href = url::base($index).$href;
304 $length = strlen($suffix);
306 if ( $length > 0 AND substr_compare($href, $suffix, -$length, $length, FALSE) !== 0)
308 // Add the defined suffix
309 $href .= $suffix;
312 $attr = array
314 'rel' => $rel,
315 'type' => $type,
316 'href' => $href,
319 if ( ! empty($media))
321 // Add the media type to the attributes
322 $attr['media'] = $media;
325 $compiled = '<link'.html::attributes($attr).' />';
328 return $compiled."\n";
332 * Creates a script link.
334 * @param string|array filename
335 * @param boolean include the index_page in the link
336 * @return string
338 public static function script($script, $index = FALSE)
340 $compiled = '';
342 if (is_array($script))
344 foreach ($script as $name)
346 $compiled .= html::script($name, $index);
349 else
351 if (strpos($script, '://') === FALSE)
353 // Add the suffix only when it's not already present
354 $script = url::base((bool) $index).$script;
357 if (substr_compare($script, '.js', -3, 3, FALSE) !== 0)
359 // Add the javascript suffix
360 $script .= '.js';
363 if(class_exists('ninja')) {
364 $script = ninja::add_version_to_uri($script);
366 $compiled = '<script type="text/javascript" src="'.$script.'"></script>';
369 return $compiled."\n";
373 * Creates a image link.
375 * @param string image source, or an array of attributes
376 * @param string|array image alt attribute, or an array of attributes
377 * @param boolean include the index_page in the link
378 * @return string
380 public static function image($src = NULL, $alt = NULL, $index = FALSE)
382 // Create attribute list
383 $attributes = is_array($src) ? $src : array('src' => $src);
385 if (is_array($alt))
387 $attributes += $alt;
389 else
391 // Add alt to attributes
392 $attributes['alt'] = $alt;
395 if ($attributes['src'][0] != '/' && strpos($attributes['src'], '://') === FALSE)
397 // Make the src attribute into an absolute URL
398 $attributes['src'] = url::base($index).$attributes['src'];
401 return '<img'.html::attributes($attributes).' />';
405 * Compiles an array of HTML attributes into an attribute string.
407 * @param string|array array of attributes
408 * @return string
410 public static function attributes($attrs)
412 if (empty($attrs))
413 return '';
415 if (is_string($attrs))
416 return ' '.$attrs;
418 $compiled = '';
419 foreach ($attrs as $key => $val)
421 $compiled .= ' '.$key.'="'.html::specialchars($val).'"';
424 return $compiled;
427 } // End html