CakePHP
  • Documentation
    • Book
    • API
    • Videos
    • Reporting Security Issues
    • Privacy Policy
    • Logos & Trademarks
  • Business Solutions
  • Swag
  • Road Trip
  • Team
  • Community
    • Community
    • Get Involved
    • Issues (GitHub)
    • Bakery
    • Featured Resources
    • Training
    • Meetups
    • My CakePHP
    • CakeFest
    • Newsletter
    • Linkedin
    • YouTube
    • Facebook
    • Twitter
    • Mastodon
    • Help & Support
    • Forum
    • Stack Overflow
    • Slack
    • Paid Support
CakePHP

C CakePHP 2.1 API

  • Overview
  • Tree
  • Deprecated
  • Version:
    • 2.1
      • 4.2
      • 4.1
      • 4.0
      • 3.9
      • 3.8
      • 3.7
      • 3.6
      • 3.5
      • 3.4
      • 3.3
      • 3.2
      • 3.1
      • 3.0
      • 2.10
      • 2.9
      • 2.8
      • 2.7
      • 2.6
      • 2.5
      • 2.4
      • 2.3
      • 2.2
      • 2.1
      • 2.0
      • 1.3
      • 1.2

Packages

  • Cake
    • Cache
      • Engine
    • Configure
    • Console
      • Command
        • Task
    • Controller
      • Component
        • Acl
        • Auth
    • Core
    • Error
    • Event
    • I18n
    • Log
      • Engine
    • Model
      • Behavior
      • Datasource
        • Database
        • Session
    • Network
      • Email
      • Http
    • Routing
      • Route
    • TestSuite
      • Coverage
      • Fixture
      • Reporter
    • Utility
    • View
      • Helper

Classes

  • CacheHelper
  • FormHelper
  • HtmlHelper
  • JqueryEngineHelper
  • JsBaseEngineHelper
  • JsHelper
  • MootoolsEngineHelper
  • NumberHelper
  • PaginatorHelper
  • PrototypeEngineHelper
  • RssHelper
  • SessionHelper
  • TextHelper
  • TimeHelper
   1: <?php
   2: /**
   3:  * Html Helper class file.
   4:  *
   5:  * Simplifies the construction of HTML elements.
   6:  *
   7:  * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
   8:  * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
   9:  *
  10:  * Licensed under The MIT License
  11:  * Redistributions of files must retain the above copyright notice.
  12:  *
  13:  * @copyright     Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
  14:  * @link          http://cakephp.org CakePHP(tm) Project
  15:  * @package       Cake.View.Helper
  16:  * @since         CakePHP(tm) v 0.9.1
  17:  * @license       MIT License (http://www.opensource.org/licenses/mit-license.php)
  18:  */
  19: 
  20: App::uses('AppHelper', 'View/Helper');
  21: App::uses('CakeResponse', 'Network');
  22: 
  23: /**
  24:  * Html Helper class for easy use of HTML widgets.
  25:  *
  26:  * HtmlHelper encloses all methods needed while working with HTML pages.
  27:  *
  28:  * @package       Cake.View.Helper
  29:  * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/html.html
  30:  */
  31: class HtmlHelper extends AppHelper {
  32: 
  33: /**
  34:  * Reference to the Response object
  35:  *
  36:  * @var CakeResponse
  37:  */
  38:     public $response;
  39: 
  40: /**
  41:  * html tags used by this helper.
  42:  *
  43:  * @var array
  44:  */
  45:     protected $_tags = array(
  46:         'meta' => '<meta%s/>',
  47:         'metalink' => '<link href="%s"%s/>',
  48:         'link' => '<a href="%s"%s>%s</a>',
  49:         'mailto' => '<a href="mailto:%s" %s>%s</a>',
  50:         'form' => '<form action="%s"%s>',
  51:         'formend' => '</form>',
  52:         'input' => '<input name="%s"%s/>',
  53:         'textarea' => '<textarea name="%s"%s>%s</textarea>',
  54:         'hidden' => '<input type="hidden" name="%s"%s/>',
  55:         'checkbox' => '<input type="checkbox" name="%s" %s/>',
  56:         'checkboxmultiple' => '<input type="checkbox" name="%s[]"%s />',
  57:         'radio' => '<input type="radio" name="%s" id="%s"%s />%s',
  58:         'selectstart' => '<select name="%s"%s>',
  59:         'selectmultiplestart' => '<select name="%s[]"%s>',
  60:         'selectempty' => '<option value=""%s>&nbsp;</option>',
  61:         'selectoption' => '<option value="%s"%s>%s</option>',
  62:         'selectend' => '</select>',
  63:         'optiongroup' => '<optgroup label="%s"%s>',
  64:         'optiongroupend' => '</optgroup>',
  65:         'checkboxmultiplestart' => '',
  66:         'checkboxmultipleend' => '',
  67:         'password' => '<input type="password" name="%s" %s/>',
  68:         'file' => '<input type="file" name="%s" %s/>',
  69:         'file_no_model' => '<input type="file" name="%s" %s/>',
  70:         'submit' => '<input %s/>',
  71:         'submitimage' => '<input type="image" src="%s" %s/>',
  72:         'button' => '<button%s>%s</button>',
  73:         'image' => '<img src="%s" %s/>',
  74:         'tableheader' => '<th%s>%s</th>',
  75:         'tableheaderrow' => '<tr%s>%s</tr>',
  76:         'tablecell' => '<td%s>%s</td>',
  77:         'tablerow' => '<tr%s>%s</tr>',
  78:         'block' => '<div%s>%s</div>',
  79:         'blockstart' => '<div%s>',
  80:         'blockend' => '</div>',
  81:         'tag' => '<%s%s>%s</%s>',
  82:         'tagstart' => '<%s%s>',
  83:         'tagend' => '</%s>',
  84:         'tagselfclosing' => '<%s%s/>',
  85:         'para' => '<p%s>%s</p>',
  86:         'parastart' => '<p%s>',
  87:         'label' => '<label for="%s"%s>%s</label>',
  88:         'fieldset' => '<fieldset%s>%s</fieldset>',
  89:         'fieldsetstart' => '<fieldset><legend>%s</legend>',
  90:         'fieldsetend' => '</fieldset>',
  91:         'legend' => '<legend>%s</legend>',
  92:         'css' => '<link rel="%s" type="text/css" href="%s" %s/>',
  93:         'style' => '<style type="text/css"%s>%s</style>',
  94:         'charset' => '<meta http-equiv="Content-Type" content="text/html; charset=%s" />',
  95:         'ul' => '<ul%s>%s</ul>',
  96:         'ol' => '<ol%s>%s</ol>',
  97:         'li' => '<li%s>%s</li>',
  98:         'error' => '<div%s>%s</div>',
  99:         'javascriptblock' => '<script type="text/javascript"%s>%s</script>',
 100:         'javascriptstart' => '<script type="text/javascript">',
 101:         'javascriptlink' => '<script type="text/javascript" src="%s"%s></script>',
 102:         'javascriptend' => '</script>'
 103:     );
 104: 
 105: /**
 106:  * Breadcrumbs.
 107:  *
 108:  * @var array
 109:  */
 110:     protected $_crumbs = array();
 111: 
 112: /**
 113:  * Names of script files that have been included once
 114:  *
 115:  * @var array
 116:  */
 117:     protected $_includedScripts = array();
 118: 
 119: /**
 120:  * Options for the currently opened script block buffer if any.
 121:  *
 122:  * @var array
 123:  */
 124:     protected $_scriptBlockOptions = array();
 125: 
 126: /**
 127:  * Document type definitions
 128:  *
 129:  * @var array
 130:  */
 131:     protected $_docTypes = array(
 132:         'html4-strict' => '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">',
 133:         'html4-trans' => '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">',
 134:         'html4-frame' => '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">',
 135:         'html5' => '<!DOCTYPE html>',
 136:         'xhtml-strict' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">',
 137:         'xhtml-trans' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">',
 138:         'xhtml-frame' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">',
 139:         'xhtml11' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">'
 140:     );
 141: 
 142: /**
 143:  * Constructor
 144:  *
 145:  * ### Settings
 146:  *
 147:  * - `configFile` A file containing an array of tags you wish to redefine.
 148:  *
 149:  * ### Customizing tag sets
 150:  *
 151:  * Using the `configFile` option you can redefine the tag HtmlHelper will use.
 152:  * The file named should be compatible with HtmlHelper::loadConfig().
 153:  *
 154:  * @param View $View The View this helper is being attached to.
 155:  * @param array $settings Configuration settings for the helper.
 156:  */
 157:     public function __construct(View $View, $settings = array()) {
 158:         parent::__construct($View, $settings);
 159:         if (is_object($this->_View->response)) {
 160:             $this->response = $this->_View->response;
 161:         } else {
 162:             $this->response = new CakeResponse(array('charset' => Configure::read('App.encoding')));
 163:         }
 164:         if (!empty($settings['configFile'])) {
 165:             $this->loadConfig($settings['configFile']);
 166:         }
 167:     }
 168: 
 169: /**
 170:  * Adds a link to the breadcrumbs array.
 171:  *
 172:  * @param string $name Text for link
 173:  * @param string $link URL for link (if empty it won't be a link)
 174:  * @param mixed $options Link attributes e.g. array('id' => 'selected')
 175:  * @return void
 176:  * @see HtmlHelper::link() for details on $options that can be used.
 177:  * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/html.html#creating-breadcrumb-trails-with-htmlhelper
 178:  */
 179:     public function addCrumb($name, $link = null, $options = null) {
 180:         $this->_crumbs[] = array($name, $link, $options);
 181:     }
 182: 
 183: /**
 184:  * Returns a doctype string.
 185:  *
 186:  * Possible doctypes:
 187:  *
 188:  *  - html4-strict:  HTML4 Strict.
 189:  *  - html4-trans:  HTML4 Transitional.
 190:  *  - html4-frame:  HTML4 Frameset.
 191:  *  - html5: HTML5. Default value.
 192:  *  - xhtml-strict: XHTML1 Strict.
 193:  *  - xhtml-trans: XHTML1 Transitional.
 194:  *  - xhtml-frame: XHTML1 Frameset.
 195:  *  - xhtml11: XHTML1.1.
 196:  *
 197:  * @param string $type Doctype to use.
 198:  * @return string Doctype string
 199:  * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/html.html#HtmlHelper::docType
 200:  */
 201:     public function docType($type = 'html5') {
 202:         if (isset($this->_docTypes[$type])) {
 203:             return $this->_docTypes[$type];
 204:         }
 205:         return null;
 206:     }
 207: 
 208: /**
 209:  * Creates a link to an external resource and handles basic meta tags
 210:  *
 211:  * Create a meta tag that is output inline:
 212:  *
 213:  * `$this->Html->meta('icon', 'favicon.ico');
 214:  *
 215:  * Append the meta tag to `$scripts_for_layout`:
 216:  *
 217:  * `$this->Html->meta('description', 'A great page', array('inline' => false));`
 218:  *
 219:  * Append the meta tag to custom view block:
 220:  *
 221:  * `$this->Html->meta('description', 'A great page', array('block' => 'metaTags'));`
 222:  *
 223:  * ### Options
 224:  *
 225:  * - `inline` Whether or not the link element should be output inline. Set to false to
 226:  *   have the meta tag included in `$scripts_for_layout`, and appended to the 'meta' view block.
 227:  * - `block` Choose a custom block to append the meta tag to.  Using this option
 228:  *   will override the inline option.
 229:  *
 230:  * @param string $type The title of the external resource
 231:  * @param mixed $url The address of the external resource or string for content attribute
 232:  * @param array $options Other attributes for the generated tag. If the type attribute is html,
 233:  *    rss, atom, or icon, the mime-type is returned.
 234:  * @return string A completed `<link />` element.
 235:  * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/html.html#HtmlHelper::meta
 236:  */
 237:     public function meta($type, $url = null, $options = array()) {
 238:         $options += array('inline' => true, 'block' => null);
 239:         if (!$options['inline'] && empty($options['block'])) {
 240:             $options['block'] = __FUNCTION__;
 241:         }
 242:         unset($options['inline']);
 243: 
 244:         if (!is_array($type)) {
 245:             $types = array(
 246:                 'rss' => array('type' => 'application/rss+xml', 'rel' => 'alternate', 'title' => $type, 'link' => $url),
 247:                 'atom' => array('type' => 'application/atom+xml', 'title' => $type, 'link' => $url),
 248:                 'icon' => array('type' => 'image/x-icon', 'rel' => 'icon', 'link' => $url),
 249:                 'keywords' => array('name' => 'keywords', 'content' => $url),
 250:                 'description' => array('name' => 'description', 'content' => $url),
 251:             );
 252: 
 253:             if ($type === 'icon' && $url === null) {
 254:                 $types['icon']['link'] = $this->webroot('favicon.ico');
 255:             }
 256: 
 257:             if (isset($types[$type])) {
 258:                 $type = $types[$type];
 259:             } elseif (!isset($options['type']) && $url !== null) {
 260:                 if (is_array($url) && isset($url['ext'])) {
 261:                     $type = $types[$url['ext']];
 262:                 } else {
 263:                     $type = $types['rss'];
 264:                 }
 265:             } elseif (isset($options['type']) && isset($types[$options['type']])) {
 266:                 $type = $types[$options['type']];
 267:                 unset($options['type']);
 268:             } else {
 269:                 $type = array();
 270:             }
 271:         } elseif ($url !== null) {
 272:             $inline = $url;
 273:         }
 274:         $options = array_merge($type, $options);
 275:         $out = null;
 276: 
 277:         if (isset($options['link'])) {
 278:             if (isset($options['rel']) && $options['rel'] === 'icon') {
 279:                 $out = sprintf($this->_tags['metalink'], $options['link'], $this->_parseAttributes($options, array('block', 'link'), ' ', ' '));
 280:                 $options['rel'] = 'shortcut icon';
 281:             } else {
 282:                 $options['link'] = $this->url($options['link'], true);
 283:             }
 284:             $out .= sprintf($this->_tags['metalink'], $options['link'], $this->_parseAttributes($options, array('block', 'link'), ' ', ' '));
 285:         } else {
 286:             $out = sprintf($this->_tags['meta'], $this->_parseAttributes($options, array('block', 'type'), ' ', ' '));
 287:         }
 288: 
 289:         if (empty($options['block'])) {
 290:             return $out;
 291:         } else {
 292:             $this->_View->append($options['block'], $out);
 293:         }
 294:     }
 295: 
 296: /**
 297:  * Returns a charset META-tag.
 298:  *
 299:  * @param string $charset The character set to be used in the meta tag. If empty,
 300:  *  The App.encoding value will be used. Example: "utf-8".
 301:  * @return string A meta tag containing the specified character set.
 302:  * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/html.html#HtmlHelper::charset
 303:  */
 304:     public function charset($charset = null) {
 305:         if (empty($charset)) {
 306:             $charset = strtolower(Configure::read('App.encoding'));
 307:         }
 308:         return sprintf($this->_tags['charset'], (!empty($charset) ? $charset : 'utf-8'));
 309:     }
 310: 
 311: /**
 312:  * Creates an HTML link.
 313:  *
 314:  * If $url starts with "http://" this is treated as an external link. Else,
 315:  * it is treated as a path to controller/action and parsed with the
 316:  * HtmlHelper::url() method.
 317:  *
 318:  * If the $url is empty, $title is used instead.
 319:  *
 320:  * ### Options
 321:  *
 322:  * - `escape` Set to false to disable escaping of title and attributes.
 323:  * - `confirm` JavaScript confirmation message.
 324:  *
 325:  * @param string $title The content to be wrapped by <a> tags.
 326:  * @param mixed $url Cake-relative URL or array of URL parameters, or external URL (starts with http://)
 327:  * @param array $options Array of HTML attributes.
 328:  * @param string $confirmMessage JavaScript confirmation message.
 329:  * @return string An `<a />` element.
 330:  * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/html.html#HtmlHelper::link
 331:  */
 332:     public function link($title, $url = null, $options = array(), $confirmMessage = false) {
 333:         $escapeTitle = true;
 334:         if ($url !== null) {
 335:             $url = $this->url($url);
 336:         } else {
 337:             $url = $this->url($title);
 338:             $title = h(urldecode($url));
 339:             $escapeTitle = false;
 340:         }
 341: 
 342:         if (isset($options['escape'])) {
 343:             $escapeTitle = $options['escape'];
 344:         }
 345: 
 346:         if ($escapeTitle === true) {
 347:             $title = h($title);
 348:         } elseif (is_string($escapeTitle)) {
 349:             $title = htmlentities($title, ENT_QUOTES, $escapeTitle);
 350:         }
 351: 
 352:         if (!empty($options['confirm'])) {
 353:             $confirmMessage = $options['confirm'];
 354:             unset($options['confirm']);
 355:         }
 356:         if ($confirmMessage) {
 357:             $confirmMessage = str_replace("'", "\'", $confirmMessage);
 358:             $confirmMessage = str_replace('"', '\"', $confirmMessage);
 359:             $options['onclick'] = "return confirm('{$confirmMessage}');";
 360:         } elseif (isset($options['default']) && $options['default'] == false) {
 361:             if (isset($options['onclick'])) {
 362:                 $options['onclick'] .= ' event.returnValue = false; return false;';
 363:             } else {
 364:                 $options['onclick'] = 'event.returnValue = false; return false;';
 365:             }
 366:             unset($options['default']);
 367:         }
 368:         return sprintf($this->_tags['link'], $url, $this->_parseAttributes($options), $title);
 369:     }
 370: 
 371: /**
 372:  * Creates a link element for CSS stylesheets.
 373:  *
 374:  * ### Usage
 375:  *
 376:  * Include one CSS file:
 377:  *
 378:  * `echo $this->Html->css('styles.css');`
 379:  *
 380:  * Include multiple CSS files:
 381:  *
 382:  * `echo $this->Html->css(array('one.css', 'two.css'));`
 383:  *
 384:  * Add the stylesheet to the `$scripts_for_layout` layout var:
 385:  *
 386:  * `$this->Html->css('styles.css', null, array('inline' => false));`
 387:  *
 388:  * Add the stylesheet to a custom block:
 389:  *
 390:  * `$this->Html->css('styles.css', null, array('block' => 'layoutCss'));`
 391:  *
 392:  * ### Options
 393:  *
 394:  * - `inline` If set to false, the generated tag will be appended to the 'css' block,
 395:  *   and included in the `$scripts_for_layout` layout variable. Defaults to true.
 396:  * - `block` Set the name of the block link/style tag will be appended to.  This overrides the `inline`
 397:  *   option.
 398:  * - `plugin` False value will prevent parsing path as a plugin
 399:  *
 400:  * @param mixed $path The name of a CSS style sheet or an array containing names of
 401:  *   CSS stylesheets. If `$path` is prefixed with '/', the path will be relative to the webroot
 402:  *   of your application. Otherwise, the path will be relative to your CSS path, usually webroot/css.
 403:  * @param string $rel Rel attribute. Defaults to "stylesheet". If equal to 'import' the stylesheet will be imported.
 404:  * @param array $options Array of HTML attributes.
 405:  * @return string CSS <link /> or <style /> tag, depending on the type of link.
 406:  * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/html.html#HtmlHelper::css
 407:  */
 408:     public function css($path, $rel = null, $options = array()) {
 409:         $options += array('block' => null, 'inline' => true);
 410:         if (!$options['inline'] && empty($options['block'])) {
 411:             $options['block'] = __FUNCTION__;
 412:         }
 413:         unset($options['inline']);
 414: 
 415:         if (is_array($path)) {
 416:             $out = '';
 417:             foreach ($path as $i) {
 418:                 $out .= "\n\t" . $this->css($i, $rel, $options);
 419:             }
 420:             if (empty($options['block'])) {
 421:                 return $out . "\n";
 422:             }
 423:             return;
 424:         }
 425: 
 426:         if (strpos($path, '//') !== false) {
 427:             $url = $path;
 428:         } else {
 429:             $url = $this->assetUrl($path, $options + array('pathPrefix' => CSS_URL, 'ext' => '.css'));
 430: 
 431:             if (Configure::read('Asset.filter.css')) {
 432:                 $pos = strpos($url, CSS_URL);
 433:                 if ($pos !== false) {
 434:                     $url = substr($url, 0, $pos) . 'ccss/' . substr($url, $pos + strlen(CSS_URL));
 435:                 }
 436:             }
 437:         }
 438: 
 439:         if ($rel == 'import') {
 440:             $out = sprintf($this->_tags['style'], $this->_parseAttributes($options, array('inline', 'block'), '', ' '), '@import url(' . $url . ');');
 441:         } else {
 442:             if ($rel == null) {
 443:                 $rel = 'stylesheet';
 444:             }
 445:             $out = sprintf($this->_tags['css'], $rel, $url, $this->_parseAttributes($options, array('inline', 'block'), '', ' '));
 446:         }
 447: 
 448:         if (empty($options['block'])) {
 449:             return $out;
 450:         } else {
 451:             $this->_View->append($options['block'], $out);
 452:         }
 453:     }
 454: 
 455: /**
 456:  * Returns one or many `<script>` tags depending on the number of scripts given.
 457:  *
 458:  * If the filename is prefixed with "/", the path will be relative to the base path of your
 459:  * application.  Otherwise, the path will be relative to your JavaScript path, usually webroot/js.
 460:  *
 461:  *
 462:  * ### Usage
 463:  *
 464:  * Include one script file:
 465:  *
 466:  * `echo $this->Html->script('styles.js');`
 467:  *
 468:  * Include multiple script files:
 469:  *
 470:  * `echo $this->Html->script(array('one.js', 'two.js'));`
 471:  *
 472:  * Add the script file to the `$scripts_for_layout` layout var:
 473:  *
 474:  * `$this->Html->script('styles.js', array('inline' => false));`
 475:  *
 476:  * Add the script file to a custom block:
 477:  *
 478:  * `$this->Html->script('styles.js', null, array('block' => 'bodyScript'));`
 479:  *
 480:  * ### Options
 481:  *
 482:  * - `inline` Whether script should be output inline or into `$scripts_for_layout`. When set to false,
 483:  *   the script tag will be appended to the 'script' view block as well as `$scripts_for_layout`.
 484:  * - `block` The name of the block you want the script appended to.  Leave undefined to output inline.
 485:  *   Using this option will override the inline option.
 486:  * - `once` Whether or not the script should be checked for uniqueness. If true scripts will only be
 487:  *   included once, use false to allow the same script to be included more than once per request.
 488:  * - `plugin` False value will prevent parsing path as a plugin
 489:  *
 490:  * @param mixed $url String or array of javascript files to include
 491:  * @param mixed $options Array of options, and html attributes see above. If boolean sets $options['inline'] = value
 492:  * @return mixed String of `<script />` tags or null if $inline is false or if $once is true and the file has been
 493:  *   included before.
 494:  * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/html.html#HtmlHelper::script
 495:  */
 496:     public function script($url, $options = array()) {
 497:         if (is_bool($options)) {
 498:             list($inline, $options) = array($options, array());
 499:             $options['inline'] = $inline;
 500:         }
 501:         $options = array_merge(array('block' => null, 'inline' => true, 'once' => true), $options);
 502:         if (!$options['inline'] && empty($options['block'])) {
 503:             $options['block'] = __FUNCTION__;
 504:         }
 505:         unset($options['inline']);
 506: 
 507:         if (is_array($url)) {
 508:             $out = '';
 509:             foreach ($url as $i) {
 510:                 $out .= "\n\t" . $this->script($i, $options);
 511:             }
 512:             if (empty($options['block'])) {
 513:                 return $out . "\n";
 514:             }
 515:             return null;
 516:         }
 517:         if ($options['once'] && isset($this->_includedScripts[$url])) {
 518:             return null;
 519:         }
 520:         $this->_includedScripts[$url] = true;
 521: 
 522:         if (strpos($url, '//') === false) {
 523:             $url = $this->assetUrl($url, $options + array('pathPrefix' => JS_URL, 'ext' => '.js'));
 524: 
 525:             if (Configure::read('Asset.filter.js')) {
 526:                 $url = str_replace(JS_URL, 'cjs/', $url);
 527:             }
 528:         }
 529:         $attributes = $this->_parseAttributes($options, array('block', 'once'), ' ');
 530:         $out = sprintf($this->_tags['javascriptlink'], $url, $attributes);
 531: 
 532:         if (empty($options['block'])) {
 533:             return $out;
 534:         } else {
 535:             $this->_View->append($options['block'], $out);
 536:         }
 537:     }
 538: 
 539: /**
 540:  * Wrap $script in a script tag.
 541:  *
 542:  * ### Options
 543:  *
 544:  * - `safe` (boolean) Whether or not the $script should be wrapped in <![CDATA[ ]]>
 545:  * - `inline` (boolean) Whether or not the $script should be added to
 546:  *   `$scripts_for_layout` / `script` block, or output inline. (Deprecated, use `block` instead)
 547:  * - `block` Which block you want this script block appended to.
 548:  *   Defaults to `script`.
 549:  *
 550:  * @param string $script The script to wrap
 551:  * @param array $options The options to use. Options not listed above will be
 552:  *    treated as HTML attributes.
 553:  * @return mixed string or null depending on the value of `$options['block']`
 554:  * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/html.html#HtmlHelper::scriptBlock
 555:  */
 556:     public function scriptBlock($script, $options = array()) {
 557:         $options += array('safe' => true, 'inline' => true);
 558:         if ($options['safe']) {
 559:             $script  = "\n" . '//<![CDATA[' . "\n" . $script . "\n" . '//]]>' . "\n";
 560:         }
 561:         if (!$options['inline'] && empty($options['block'])) {
 562:             $options['block'] = 'script';
 563:         }
 564:         unset($options['inline'], $options['safe']);
 565: 
 566:         $attributes = $this->_parseAttributes($options, array('block'), ' ');
 567:         $out = sprintf($this->_tags['javascriptblock'], $attributes, $script);
 568: 
 569:         if (empty($options['block'])) {
 570:             return $out;
 571:         } else {
 572:             $this->_View->append($options['block'], $out);
 573:         }
 574:     }
 575: 
 576: /**
 577:  * Begin a script block that captures output until HtmlHelper::scriptEnd()
 578:  * is called. This capturing block will capture all output between the methods
 579:  * and create a scriptBlock from it.
 580:  *
 581:  * ### Options
 582:  *
 583:  * - `safe` Whether the code block should contain a CDATA
 584:  * - `inline` Should the generated script tag be output inline or in `$scripts_for_layout`
 585:  *
 586:  * @param array $options Options for the code block.
 587:  * @return void
 588:  * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/html.html#HtmlHelper::scriptStart
 589:  */
 590:     public function scriptStart($options = array()) {
 591:         $options += array('safe' => true, 'inline' => true);
 592:         $this->_scriptBlockOptions = $options;
 593:         ob_start();
 594:         return null;
 595:     }
 596: 
 597: /**
 598:  * End a Buffered section of Javascript capturing.
 599:  * Generates a script tag inline or in `$scripts_for_layout` depending on the settings
 600:  * used when the scriptBlock was started
 601:  *
 602:  * @return mixed depending on the settings of scriptStart() either a script tag or null
 603:  * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/html.html#HtmlHelper::scriptEnd
 604:  */
 605:     public function scriptEnd() {
 606:         $buffer = ob_get_clean();
 607:         $options = $this->_scriptBlockOptions;
 608:         $this->_scriptBlockOptions = array();
 609:         return $this->scriptBlock($buffer, $options);
 610:     }
 611: 
 612: /**
 613:  * Builds CSS style data from an array of CSS properties
 614:  *
 615:  * ### Usage:
 616:  *
 617:  * {{{
 618:  * echo $html->style(array('margin' => '10px', 'padding' => '10px'), true);
 619:  *
 620:  * // creates
 621:  * 'margin:10px;padding:10px;'
 622:  * }}}
 623:  *
 624:  * @param array $data Style data array, keys will be used as property names, values as property values.
 625:  * @param boolean $oneline Whether or not the style block should be displayed on one line.
 626:  * @return string CSS styling data
 627:  * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/html.html#HtmlHelper::style
 628:  */
 629:     public function style($data, $oneline = true) {
 630:         if (!is_array($data)) {
 631:             return $data;
 632:         }
 633:         $out = array();
 634:         foreach ($data as $key => $value) {
 635:             $out[] = $key . ':' . $value . ';';
 636:         }
 637:         if ($oneline) {
 638:             return join(' ', $out);
 639:         }
 640:         return implode("\n", $out);
 641:     }
 642: 
 643: /**
 644:  * Returns the breadcrumb trail as a sequence of &raquo;-separated links.
 645:  *
 646:  * If `$startText` is an array, the accepted keys are:
 647:  *
 648:  * - `text` Define the text/content for the link.
 649:  * - `url` Define the target of the created link.
 650:  *
 651:  * All other keys will be passed to HtmlHelper::link() as the `$options` parameter.
 652:  *
 653:  * @param string $separator Text to separate crumbs.
 654:  * @param mixed $startText This will be the first crumb, if false it defaults to first crumb in array. Can
 655:  *   also be an array, see above for details.
 656:  * @return string Composed bread crumbs
 657:  * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/html.html#creating-breadcrumb-trails-with-htmlhelper
 658:  */
 659:     public function getCrumbs($separator = '&raquo;', $startText = false) {
 660:         $crumbs = $this->_prepareCrumbs($startText);
 661:         if (!empty($crumbs)) {
 662:             $out = array();
 663:             foreach ($crumbs as $crumb) {
 664:                 if (!empty($crumb[1])) {
 665:                     $out[] = $this->link($crumb[0], $crumb[1], $crumb[2]);
 666:                 } else {
 667:                     $out[] = $crumb[0];
 668:                 }
 669:             }
 670:             return join($separator, $out);
 671:         } else {
 672:             return null;
 673:         }
 674:     }
 675: 
 676: /**
 677:  * Returns breadcrumbs as a (x)html list
 678:  *
 679:  * This method uses HtmlHelper::tag() to generate list and its elements. Works
 680:  * similar to HtmlHelper::getCrumbs(), so it uses options which every
 681:  * crumb was added with.
 682:  *
 683:  * @param array $options Array of html attributes to apply to the generated list elements.
 684:  * @param mixed $startText This will be the first crumb, if false it defaults to first crumb in array. Can
 685:  *   also be an array, see `HtmlHelper::getCrumbs` for details.
 686:  * @return string breadcrumbs html list
 687:  * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/html.html#creating-breadcrumb-trails-with-htmlhelper
 688:  */
 689:     public function getCrumbList($options = array(), $startText = false) {
 690:         $crumbs = $this->_prepareCrumbs($startText);
 691:         if (!empty($crumbs)) {
 692:             $result = '';
 693:             $crumbCount = count($crumbs);
 694:             $ulOptions = $options;
 695:             foreach ($crumbs as $which => $crumb) {
 696:                 $options = array();
 697:                 if (empty($crumb[1])) {
 698:                     $elementContent = $crumb[0];
 699:                 } else {
 700:                     $elementContent = $this->link($crumb[0], $crumb[1], $crumb[2]);
 701:                 }
 702:                 if ($which == 0) {
 703:                     $options['class'] = 'first';
 704:                 } elseif ($which == $crumbCount - 1) {
 705:                     $options['class'] = 'last';
 706:                 }
 707:                 $result .= $this->tag('li', $elementContent, $options);
 708:             }
 709:             return $this->tag('ul', $result, $ulOptions);
 710:         } else {
 711:             return null;
 712:         }
 713:     }
 714: 
 715: /**
 716:  * Prepends startText to crumbs array if set
 717:  *
 718:  * @param $startText
 719:  * @return array Crumb list including startText (if provided)
 720:  */
 721:     protected function _prepareCrumbs($startText) {
 722:         $crumbs = $this->_crumbs;
 723:         if ($startText) {
 724:             if (!is_array($startText)) {
 725:                 $startText = array(
 726:                     'url' => '/',
 727:                     'text' => $startText
 728:                 );
 729:             }
 730:             $startText += array('url' => '/', 'text' => __('Home'));
 731:             list($url, $text) = array($startText['url'], $startText['text']);
 732:             unset($startText['url'], $startText['text']);
 733:             array_unshift($crumbs, array($text, $url, $startText));
 734:         }
 735:         return $crumbs;
 736:     }
 737: 
 738: /**
 739:  * Creates a formatted IMG element.
 740:  *
 741:  * This method will set an empty alt attribute if one is not supplied.
 742:  *
 743:  * ### Usage:
 744:  *
 745:  * Create a regular image:
 746:  *
 747:  * `echo $html->image('cake_icon.png', array('alt' => 'CakePHP'));`
 748:  *
 749:  * Create an image link:
 750:  *
 751:  * `echo $html->image('cake_icon.png', array('alt' => 'CakePHP', 'url' => 'http://cakephp.org'));`
 752:  *
 753:  * ### Options:
 754:  *
 755:  * - `url` If provided an image link will be generated and the link will point at
 756:  *   `$options['url']`.
 757:  * - `fullBase` If true the src attribute will get a full address for the image file.
 758:  * - `plugin` False value will prevent parsing path as a plugin
 759:  *
 760:  * @param string $path Path to the image file, relative to the app/webroot/img/ directory.
 761:  * @param array $options Array of HTML attributes.  See above for special options.
 762:  * @return string completed img tag
 763:  * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/html.html#HtmlHelper::image
 764:  */
 765:     public function image($path, $options = array()) {
 766:         $path = $this->assetUrl($path, $options + array('pathPrefix' => IMAGES_URL));
 767:         $options = array_diff_key($options, array('fullBase' => '', 'pathPrefix' => ''));
 768: 
 769:         if (!isset($options['alt'])) {
 770:             $options['alt'] = '';
 771:         }
 772: 
 773:         $url = false;
 774:         if (!empty($options['url'])) {
 775:             $url = $options['url'];
 776:             unset($options['url']);
 777:         }
 778: 
 779:         $image = sprintf($this->_tags['image'], $path, $this->_parseAttributes($options, null, '', ' '));
 780: 
 781:         if ($url) {
 782:             return sprintf($this->_tags['link'], $this->url($url), null, $image);
 783:         }
 784:         return $image;
 785:     }
 786: 
 787: /**
 788:  * Returns a row of formatted and named TABLE headers.
 789:  *
 790:  * @param array $names Array of tablenames.
 791:  * @param array $trOptions HTML options for TR elements.
 792:  * @param array $thOptions HTML options for TH elements.
 793:  * @return string Completed table headers
 794:  * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/html.html#HtmlHelper::tableHeaders
 795:  */
 796:     public function tableHeaders($names, $trOptions = null, $thOptions = null) {
 797:         $out = array();
 798:         foreach ($names as $arg) {
 799:             $out[] = sprintf($this->_tags['tableheader'], $this->_parseAttributes($thOptions), $arg);
 800:         }
 801:         return sprintf($this->_tags['tablerow'], $this->_parseAttributes($trOptions), join(' ', $out));
 802:     }
 803: 
 804: /**
 805:  * Returns a formatted string of table rows (TR's with TD's in them).
 806:  *
 807:  * @param array $data Array of table data
 808:  * @param array $oddTrOptions HTML options for odd TR elements if true useCount is used
 809:  * @param array $evenTrOptions HTML options for even TR elements
 810:  * @param boolean $useCount adds class "column-$i"
 811:  * @param boolean $continueOddEven If false, will use a non-static $count variable,
 812:  *    so that the odd/even count is reset to zero just for that call.
 813:  * @return string Formatted HTML
 814:  * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/html.html#HtmlHelper::tableCells
 815:  */
 816:     public function tableCells($data, $oddTrOptions = null, $evenTrOptions = null, $useCount = false, $continueOddEven = true) {
 817:         if (empty($data[0]) || !is_array($data[0])) {
 818:             $data = array($data);
 819:         }
 820: 
 821:         if ($oddTrOptions === true) {
 822:             $useCount = true;
 823:             $oddTrOptions = null;
 824:         }
 825: 
 826:         if ($evenTrOptions === false) {
 827:             $continueOddEven = false;
 828:             $evenTrOptions = null;
 829:         }
 830: 
 831:         if ($continueOddEven) {
 832:             static $count = 0;
 833:         } else {
 834:             $count = 0;
 835:         }
 836: 
 837:         foreach ($data as $line) {
 838:             $count++;
 839:             $cellsOut = array();
 840:             $i = 0;
 841:             foreach ($line as $cell) {
 842:                 $cellOptions = array();
 843: 
 844:                 if (is_array($cell)) {
 845:                     $cellOptions = $cell[1];
 846:                     $cell = $cell[0];
 847:                 } elseif ($useCount) {
 848:                     $cellOptions['class'] = 'column-' . ++$i;
 849:                 }
 850:                 $cellsOut[] = sprintf($this->_tags['tablecell'], $this->_parseAttributes($cellOptions), $cell);
 851:             }
 852:             $options = $this->_parseAttributes($count % 2 ? $oddTrOptions : $evenTrOptions);
 853:             $out[] = sprintf($this->_tags['tablerow'], $options, implode(' ', $cellsOut));
 854:         }
 855:         return implode("\n", $out);
 856:     }
 857: 
 858: /**
 859:  * Returns a formatted block tag, i.e DIV, SPAN, P.
 860:  *
 861:  * ### Options
 862:  *
 863:  * - `escape` Whether or not the contents should be html_entity escaped.
 864:  *
 865:  * @param string $name Tag name.
 866:  * @param string $text String content that will appear inside the div element.
 867:  *   If null, only a start tag will be printed
 868:  * @param array $options Additional HTML attributes of the DIV tag, see above.
 869:  * @return string The formatted tag element
 870:  * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/html.html#HtmlHelper::tag
 871:  */
 872:     public function tag($name, $text = null, $options = array()) {
 873:         if (is_array($options) && isset($options['escape']) && $options['escape']) {
 874:             $text = h($text);
 875:             unset($options['escape']);
 876:         }
 877:         if (!is_array($options)) {
 878:             $options = array('class' => $options);
 879:         }
 880:         if ($text === null) {
 881:             $tag = 'tagstart';
 882:         } else {
 883:             $tag = 'tag';
 884:         }
 885:         return sprintf($this->_tags[$tag], $name, $this->_parseAttributes($options, null, ' ', ''), $text, $name);
 886:     }
 887: 
 888: /**
 889:  * Returns a formatted existent block of $tags
 890:  *
 891:  * @param string $tag Tag name
 892:  * @return string Formatted block
 893:  * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/html.html#HtmlHelper::useTag
 894:  */
 895:     public function useTag($tag) {
 896:         if (!isset($this->_tags[$tag])) {
 897:             return '';
 898:         }
 899:         $args = func_get_args();
 900:         array_shift($args);
 901:         foreach ($args as &$arg) {
 902:             if (is_array($arg)) {
 903:                 $arg = $this->_parseAttributes($arg, null, ' ', '');
 904:             }
 905:         }
 906:         return vsprintf($this->_tags[$tag], $args);
 907:     }
 908: 
 909: /**
 910:  * Returns a formatted DIV tag for HTML FORMs.
 911:  *
 912:  * ### Options
 913:  *
 914:  * - `escape` Whether or not the contents should be html_entity escaped.
 915:  *
 916:  * @param string $class CSS class name of the div element.
 917:  * @param string $text String content that will appear inside the div element.
 918:  *   If null, only a start tag will be printed
 919:  * @param array $options Additional HTML attributes of the DIV tag
 920:  * @return string The formatted DIV element
 921:  * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/html.html#HtmlHelper::div
 922:  */
 923:     public function div($class = null, $text = null, $options = array()) {
 924:         if (!empty($class)) {
 925:             $options['class'] = $class;
 926:         }
 927:         return $this->tag('div', $text, $options);
 928:     }
 929: 
 930: /**
 931:  * Returns a formatted P tag.
 932:  *
 933:  * ### Options
 934:  *
 935:  * - `escape` Whether or not the contents should be html_entity escaped.
 936:  *
 937:  * @param string $class CSS class name of the p element.
 938:  * @param string $text String content that will appear inside the p element.
 939:  * @param array $options Additional HTML attributes of the P tag
 940:  * @return string The formatted P element
 941:  * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/html.html#HtmlHelper::para
 942:  */
 943:     public function para($class, $text, $options = array()) {
 944:         if (isset($options['escape'])) {
 945:             $text = h($text);
 946:         }
 947:         if ($class != null && !empty($class)) {
 948:             $options['class'] = $class;
 949:         }
 950:         if ($text === null) {
 951:             $tag = 'parastart';
 952:         } else {
 953:             $tag = 'para';
 954:         }
 955:         return sprintf($this->_tags[$tag], $this->_parseAttributes($options, null, ' ', ''), $text);
 956:     }
 957: 
 958: /**
 959:  * Returns an audio/video element
 960:  *
 961:  * ### Usage
 962:  *
 963:  * Using an audio file:
 964:  *
 965:  * `echo $this->Html->media('audio.mp3', array('fullBase' => true));`
 966:  *
 967:  * Outputs:
 968:  *
 969:  * `<video src="http://www.somehost.com/files/audio.mp3">Fallback text</video>`
 970:  *
 971:  * Using a video file:
 972:  *
 973:  * `echo $this->Html->media('video.mp4', array('text' => 'Fallback text'));`
 974:  *
 975:  * Outputs:
 976:  *
 977:  * `<video src="/files/video.mp4">Fallback text</video>`
 978:  *
 979:  * Using multiple video files:
 980:  *
 981:  * {{{
 982:  * echo $this->Html->media(
 983:  *      array('video.mp4', array('src' => 'video.ogv', 'type' => "video/ogg; codecs='theora, vorbis'")),
 984:  *      array('tag' => 'video', 'autoplay')
 985:  * );
 986:  * }}}
 987:  *
 988:  * Outputs:
 989:  *
 990:  * {{{
 991:  * <video autoplay="autoplay">
 992:  *      <source src="/files/video.mp4" type="video/mp4"/>
 993:  *      <source src="/files/video.ogv" type="video/ogv; codecs='theora, vorbis'"/>
 994:  * </video>
 995:  * }}}
 996:  *
 997:  * ### Options
 998:  *
 999:  * - `tag` Type of media element to generate, either "audio" or "video".
1000:  *  If tag is not provided it's guessed based on file's mime type.
1001:  * - `text` Text to include inside the audio/video tag
1002:  * - `pathPrefix` Path prefix to use for relative urls, defaults to 'files/'
1003:  * - `fullBase` If provided the src attribute will get a full address including domain name
1004:  *
1005:  * @param string|array $path Path to the video file, relative to the webroot/{$options['pathPrefix']} directory.
1006:  *  Or an array where each item itself can be a path string or an associate array containing keys `src` and `type`
1007:  * @param array $options Array of HTML attributes, and special options above.
1008:  * @return string Generated media element
1009:  */
1010:     public function media($path, $options = array()) {
1011:         $options += array(
1012:             'tag' => null,
1013:             'pathPrefix' => 'files/',
1014:             'text' => ''
1015:         );
1016: 
1017:         if (!empty($options['tag'])) {
1018:             $tag = $options['tag'];
1019:         } else {
1020:             $tag = null;
1021:         }
1022: 
1023:         if (is_array($path)) {
1024:             $sourceTags = '';
1025:             foreach ($path as &$source) {
1026:                 if (is_string($source)) {
1027:                     $source = array(
1028:                         'src' => $source,
1029:                     );
1030:                 }
1031:                 if (!isset($source['type'])) {
1032:                     $ext = pathinfo($source['src'], PATHINFO_EXTENSION);
1033:                     $source['type'] = $this->response->getMimeType($ext);
1034:                 }
1035:                 $source['src'] = $this->assetUrl($source['src'], $options);
1036:                 $sourceTags .= $this->useTag('tagselfclosing', 'source', $source);
1037:             }
1038:             unset($source);
1039:             $options['text'] = $sourceTags . $options['text'];
1040:             unset($options['fullBase']);
1041:         } else {
1042:             if (empty($path) && !empty($options['src'])) {
1043:                 $path = $options['src'];
1044:             }
1045:             $options['src'] = $this->assetUrl($path, $options);
1046:         }
1047: 
1048:         if ($tag === null) {
1049:             if (is_array($path)) {
1050:                 $mimeType = $path[0]['type'];
1051:             } else {
1052:                 $mimeType = $this->response->getMimeType(pathinfo($path, PATHINFO_EXTENSION));
1053:             }
1054:             if (preg_match('#^video/#', $mimeType)) {
1055:                 $tag = 'video';
1056:             } else {
1057:                 $tag = 'audio';
1058:             }
1059:         }
1060: 
1061:         if (isset($options['poster'])) {
1062:             $options['poster'] = $this->assetUrl($options['poster'], array('pathPrefix' => IMAGES_URL) + $options);
1063:         }
1064:         $text = $options['text'];
1065: 
1066:         $options = array_diff_key($options, array(
1067:             'tag' => '',
1068:             'fullBase' => '',
1069:             'pathPrefix' => '',
1070:             'text' => ''
1071:         ));
1072:         return $this->tag($tag, $text, $options);
1073:     }
1074: 
1075: /**
1076:  * Build a nested list (UL/OL) out of an associative array.
1077:  *
1078:  * @param array $list Set of elements to list
1079:  * @param array $options Additional HTML attributes of the list (ol/ul) tag or if ul/ol use that as tag
1080:  * @param array $itemOptions Additional HTML attributes of the list item (LI) tag
1081:  * @param string $tag Type of list tag to use (ol/ul)
1082:  * @return string The nested list
1083:  * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/html.html#HtmlHelper::nestedList
1084:  */
1085:     public function nestedList($list, $options = array(), $itemOptions = array(), $tag = 'ul') {
1086:         if (is_string($options)) {
1087:             $tag = $options;
1088:             $options = array();
1089:         }
1090:         $items = $this->_nestedListItem($list, $options, $itemOptions, $tag);
1091:         return sprintf($this->_tags[$tag], $this->_parseAttributes($options, null, ' ', ''), $items);
1092:     }
1093: 
1094: /**
1095:  * Internal function to build a nested list (UL/OL) out of an associative array.
1096:  *
1097:  * @param array $items Set of elements to list
1098:  * @param array $options Additional HTML attributes of the list (ol/ul) tag
1099:  * @param array $itemOptions Additional HTML attributes of the list item (LI) tag
1100:  * @param string $tag Type of list tag to use (ol/ul)
1101:  * @return string The nested list element
1102:  * @see HtmlHelper::nestedList()
1103:  */
1104:     protected function _nestedListItem($items, $options, $itemOptions, $tag) {
1105:         $out = '';
1106: 
1107:         $index = 1;
1108:         foreach ($items as $key => $item) {
1109:             if (is_array($item)) {
1110:                 $item = $key . $this->nestedList($item, $options, $itemOptions, $tag);
1111:             }
1112:             if (isset($itemOptions['even']) && $index % 2 == 0) {
1113:                 $itemOptions['class'] = $itemOptions['even'];
1114:             } elseif (isset($itemOptions['odd']) && $index % 2 != 0) {
1115:                 $itemOptions['class'] = $itemOptions['odd'];
1116:             }
1117:             $out .= sprintf($this->_tags['li'], $this->_parseAttributes($itemOptions, array('even', 'odd'), ' ', ''), $item);
1118:             $index++;
1119:         }
1120:         return $out;
1121:     }
1122: 
1123: /**
1124:  * Load Html tag configuration.
1125:  *
1126:  * Loads a file from APP/Config that contains tag data.  By default the file is expected
1127:  * to be compatible with PhpReader:
1128:  *
1129:  * `$this->Html->loadConfig('tags.php');`
1130:  *
1131:  * tags.php could look like:
1132:  *
1133:  * {{{
1134:  * $tags = array(
1135:  *      'meta' => '<meta %s>'
1136:  * );
1137:  * }}}
1138:  *
1139:  * If you wish to store tag definitions in another format you can give an array
1140:  * containing the file name, and reader class name:
1141:  *
1142:  * `$this->Html->loadConfig(array('tags.ini', 'ini'));`
1143:  *
1144:  * Its expected that the `tags` index will exist from any configuration file that is read.
1145:  * You can also specify the path to read the configuration file from, if APP/Config is not
1146:  * where the file is.
1147:  *
1148:  * `$this->Html->loadConfig('tags.php', APP . 'Lib' . DS);`
1149:  *
1150:  * Configuration files can define the following sections:
1151:  *
1152:  * - `tags` The tags to replace.
1153:  * - `minimizedAttributes` The attributes that are represented like `disabled="disabled"`
1154:  * - `docTypes` Additional doctypes to use.
1155:  * - `attributeFormat` Format for long attributes e.g. `'%s="%s"'`
1156:  * - `minimizedAttributeFormat` Format for minimized attributes e.g. `'%s="%s"'`
1157:  *
1158:  * @param mixed $configFile String with the config file (load using PhpReader) or an array with file and reader name
1159:  * @param string $path Path with config file
1160:  * @return mixed False to error or loaded configs
1161:  * @throws ConfigureException
1162:  * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/html.html#changing-the-tags-output-by-htmlhelper
1163:  */
1164:     public function loadConfig($configFile, $path = null) {
1165:         if (!$path) {
1166:             $path = APP . 'Config' . DS;
1167:         }
1168:         $file = null;
1169:         $reader = 'php';
1170: 
1171:         if (!is_array($configFile)) {
1172:             $file = $configFile;
1173:         } elseif (isset($configFile[0])) {
1174:             $file = $configFile[0];
1175:             if (isset($configFile[1])) {
1176:                 $reader = $configFile[1];
1177:             }
1178:         } else {
1179:             throw new ConfigureException(__d('cake_dev', 'Cannot load the configuration file. Wrong "configFile" configuration.'));
1180:         }
1181: 
1182:         $readerClass = Inflector::camelize($reader) . 'Reader';
1183:         App::uses($readerClass, 'Configure');
1184:         if (!class_exists($readerClass)) {
1185:             throw new ConfigureException(__d('cake_dev', 'Cannot load the configuration file. Unknown reader.'));
1186:         }
1187: 
1188:         $readerObj = new $readerClass($path);
1189:         $configs = $readerObj->read($file);
1190:         if (isset($configs['tags']) && is_array($configs['tags'])) {
1191:             $this->_tags = array_merge($this->_tags, $configs['tags']);
1192:         }
1193:         if (isset($configs['minimizedAttributes']) && is_array($configs['minimizedAttributes'])) {
1194:             $this->_minimizedAttributes = array_merge($this->_minimizedAttributes, $configs['minimizedAttributes']);
1195:         }
1196:         if (isset($configs['docTypes']) && is_array($configs['docTypes'])) {
1197:             $this->_docTypes = array_merge($this->_docTypes, $configs['docTypes']);
1198:         }
1199:         if (isset($configs['attributeFormat'])) {
1200:             $this->_attributeFormat = $configs['attributeFormat'];
1201:         }
1202:         if (isset($configs['minimizedAttributeFormat'])) {
1203:             $this->_minimizedAttributeFormat = $configs['minimizedAttributeFormat'];
1204:         }
1205:         return $configs;
1206:     }
1207: 
1208: }
1209: 
OpenHub
Rackspace
Rackspace
  • Business Solutions
  • Showcase
  • Documentation
  • Book
  • API
  • Videos
  • Reporting Security Issues
  • Privacy Policy
  • Logos & Trademarks
  • Community
  • Get Involved
  • Issues (GitHub)
  • Bakery
  • Featured Resources
  • Training
  • Meetups
  • My CakePHP
  • CakeFest
  • Newsletter
  • Linkedin
  • YouTube
  • Facebook
  • Twitter
  • Mastodon
  • Help & Support
  • Forum
  • Stack Overflow
  • Slack
  • Paid Support

Generated using CakePHP API Docs