Source for file Html.php
Documentation is available at Html.php
* A Framework for Creating and Using Complex Web Elements
* The purpose of this framework is to provide a library of high-level objects
* to facilitate common HTML coding tasks, such as menus, tables, and forms.
* The intent is to reduce repetitive HTML coding as much as possible, replacing
* it with a combination of configuration files and style sheets with
* standardized naming conventions.
* This framework is built on and requires the
* {@link http://framework.zend.com/ Zend Framework}.
* @author Lyle Frost <lfrost@cnz.com>
* @copyright Copyright (c) 2006-2007 Citadel Network <{@link http://www.citadelnetwork.com/}>
* @license http://www.citadelnetwork.com/license/cnzframework New BSD License
* @version $Id: Html.php 27 2007-07-19 18:47:54Z lfrost $
Zend_Loader::loadClass('Zend_Config');
Zend_Loader::loadClass('Zend_Config_Ini');
Zend_Loader::loadClass('Zend_Log');
Zend_Loader::loadClass('Zend_Log_Filter_Priority');
Zend_Loader::loadClass('Zend_Log_Writer_Stream');
* This utility class provides general HTML support methods.
* To use this class, load the class <kbd>Cnz_Html</kbd> and then call the
* static method <kbd>init()</kbd> prior to any output on the web page. The
* class is controlled by a configuration file.
* Example INI (defaults shown as comments):
* domain = www.example.com
* sslDomain = www.example.com
* ;brickDir = /slib/image/brick/
* ;buttonDir = /slib/image/button/
* <var>brickDir</var> is for link bricks such as the W3C validation bricks.
* <var>buttonDir</var> is for control buttons such as table next/prev.
* <var>indent</var> defines the string used for a single level of HTML
* <var>tmpDir</var> and <var>logDir</var> are relative to the application root
* directory, which is defined to be the parent of the web document root
* <var>logLevel</var> can be any of the log levels defined by Zend_Log (debug,
* info, notice, warn, err, crit, alert, or severe).
* Zend_Loader::loadClass('Cnz_Html');
* The <kbd>init()</kbd> method will detect the capabilities of the client web
* browser and send the appropriate HTTP headers. XHTML 1.1 will be chosen as
* the content type if the browser prefers XHTML, else the content type will be
* set to HTML 4.01 Strict. If transitional is true, these will instead be
* XHTML 1.0 Transitional and HTML 4.01 Transitional, respectively.
* <kbd>init()</kbd> also compares the list of languages in the configuration
* file to those in the <kbd>Accept-Language</kbd> header to find the best
* match. If there is no match, the language defaults to the first in the
* configuration list. The match can be retrieved using
* <kbd>getLanguage()</kbd>.
* <kbd>init()</kbd> processes the <kbd>Accept-Charset</kbd> header in the same
* way. Use <kbd>getCharSet()</kbd> to retrieve the selected character set.
* Based on the detections above, the appropriate HTTP response headers are
* generated, and all prolog information up to and including the <kbd>html</kbd>
* Given that the most common scenario for a database-driven site is to have a
* single database, <kbd>init()</kbd> has an option of connecting to that
* database. This connection is defined by passing a second argument to
* <kbd>init()</kbd> which is the name of the database configuration file. This
* is allowed to be in a separate file because it contains security information.
* The connection is a <kbd>Zend_Db_Adapter</kbd>.
* A third boolean parameter specifies whether the connection will be made
* immediately, or postponed until it is accessed.
* username = database_user
* password = database_password
* The valid database type values are: <kbd>dblib</kbd>, <kbd>firebird</kbd>,
* <kbd>informix</kbd>, <kbd>mysql</kbd>, <kbd>oci</kbd>, <kbd>odbc</kbd>,
* <kbd>pgsql</kbd>, <kbd>sqlite</kbd>. See <kbd>PDO_*</kbd> at
* {@link http://www.php.net/manual/en/ref.pdo.php}. Additionally, the non-PDO
* database types <kbd>db2</kbd> and <kbd>oracle</kbd> may be used.
* Leave the host undefined for socket connections.
* Pages using this class must be written with XHTML syntax. If the end-tag
* shorthand sequence "<kbd>/></kbd>" occurs anywhere else in the text, it must
* be replaced with "<kbd>/></kbd>" or else the "<kbd>/</kbd>" (and any
* preceding whitespace) will be stripped when the page is served as HTML.
* When using JavaScript, the value of the <kbd>type</kbd> attribute of the
* script tag should be set as follows.
* type = "<?php echo Cnz_Html::getJavascriptType(); ?>"
* There are also getter methods for several other settings.
* The following directory structure is recommended. The recommended * BASE is
* $BASE --- app Application code
* | |- form Form configurations
* | |- table Table configurations
* |- upload Temporary upload directory
* |- www Web document root
* |- image Images (local to current directory)
* | |- script Client-side Scripts
* | |- style Style Sheets
* |- script Client-side Scripts (local to current directory)
* |- style Style sheets (local to current directory)
* --- slib Server library (Apache alias)
* | |- button Control buttons
* |- script Client-side Scripts
const CONFIG_SEC_HTML = 'Html';
const CONFIG_SEC_DATABASE = 'Database';
const CONTENT_TYPE_XHTML = 'application/xhtml+xml';
const CONTENT_TYPE_HTML = 'text/html';
const JAVASCRIPT_TYPE_XHTML = 'application/javascript';
const JAVASCRIPT_TYPE_HTML = 'text/javascript';
const STYLE_TYPE = 'text/css';
const DEFAULT_BRICK_DIR = '/slib/image/brick/';
const DEFAULT_BUTTON_DIR = '/slib/image/button/';
const DEFAULT_CFG_FILE = '../cfg/html.ini';
const DEFAULT_DBCFG_FILE = '../cfg/database.ini';
const DEFAULT_CHARSET = 'utf-8';
const DEFAULT_LANGUAGE = 'en-us';
const DEFAULT_FIELD_DELIMITER = ':';
const DEFAULT_LIST_DELIMITER = ',';
const DEFAULT_LOG_DIR = 'log';
const DEFAULT_LOG_FILE = 'html.log';
const DEFAULT_LOG_LEVEL = Zend_Log::INFO;
const DEFAULT_TMP_DIR = 'tmp';
const DEFAULT_UPLOAD_DIR = 'upload';
const SCRIPT_FILE_EXT = 'js';
const STYLE_FILE_EXT = 'css';
private static $charSetArray = array(self::DEFAULT_CHARSET);
private static $languageArray = array(self::DEFAULT_LANGUAGE);
private static $transitionalFlag = false;
private static $logLevel = self::DEFAULT_LOG_LEVEL;
private static $indentLevel = 0;
private static $phpLogLevel = NULL;
private static $brickDir = self::DEFAULT_BRICK_DIR;
private static $buttonDir = self::DEFAULT_BUTTON_DIR;
private static $logDir = self::DEFAULT_LOG_DIR;
private static $logFile = self::DEFAULT_LOG_FILE;
private static $phpLogFile = NULL;
private static $tmpDir = self::DEFAULT_TMP_DIR;
private static $uploadDir = self::DEFAULT_UPLOAD_DIR;
private static $charSet = self::DEFAULT_CHARSET;
private static $contentType = self::CONTENT_TYPE_HTML;
private static $indentString = "\t";
private static $javascriptType = self::JAVASCRIPT_TYPE_HTML;
private static $language = self::DEFAULT_LANGUAGE;
private static $htmlConfigFile = NULL;
private static $dbConfigFile = NULL;
private static $domain = NULL;
private static $sslDomain = NULL;
/** For config values with multiple parts */
private static $fieldDelimiter = self::DEFAULT_FIELD_DELIMITER;
/** For config entries with list values */
private static $listDelimiter = self::DEFAULT_LIST_DELIMITER;
private static $wcagLevel = '';
/** @var Zend_Db_Adapter_Abstract */
private static $db = NULL;
private static $logger = NULL;
/* Getters/Setters ===================================================*/
/** @return string Brick directory */
/** @return string Button directory */
/** @return string Content type */
return self::$contentType;
/** @return Zend_Db Database connection */
public static function getDb()
/** @return string Domain */
/** @return string Config file field delimiter */
return self::$fieldDelimiter;
* @param string $fieldDelimiter New config file field delimiter
public static function setFieldDelimiter($fieldDelimiter = self::DEFAULT_FIELD_DELIMITER)
self::$fieldDelimiter = $fieldDelimiter;
/** @return string HTML configuration file */
return self::$htmlConfigFile;
/** @return int Indent level */
return (int) self::$indentLevel;
* @param int $indentLevel New indentation level
/** @return string Indent string */
return self::$indentString;
/** @return string Type attribute for HTML script tag */
return self::$javascriptType;
/** @return string Language code */
/** @return string Config file list delimiter */
return self::$listDelimiter;
* @param string $listDelimiter New config file list delimiter
public static function setListDelimiter($listDelimiter = self::DEFAULT_LIST_DELIMITER)
self::$listDelimiter = $listDelimiter;
/** @return Zend_Log Logger */
/** @return string SSL domain */
/** @return string Tmp directory */
/** @return string Upload directory */
/* Testers ===========================================================*/
/** @return boolean True if SSL */
public static function isSsl()
return isset ($_SERVER['HTTPS']);
/** @return boolean True if content type is XHTML */
return self::$contentType == self::CONTENT_TYPE_XHTML;
/* Static Methods ====================================================*/
* Convert an associative array to a list of the form key:val,key:val.
* If any value is itself an array, it will be expanded as
* @param string $fieldDelimiter
* @param string $listDelimiter
public static function arrayToList($array, $fieldDelimiter = NULL, $listDelimiter = NULL)
if (empty($fieldDelimiter)) $fieldDelimiter = self::$fieldDelimiter;
if (empty($listDelimiter)) $listDelimiter = self::$listDelimiter;
foreach ($array as $key => $value)
$result .= $fieldDelimiter . $v;
$result .= $fieldDelimiter . $value;
if ($i++ < $n - 1) $result .= $listDelimiter;
* Convert a configuration file string value to boolean.
* @param $value Value from configuration file
* @return boolean $value converted to boolean
* Create a database connection using the configuration information
* provided to <kbd>init()</kbd>. The default Zend_Db_Table_Abstract
* adapter is set to this connection. The connection is actually
* established if nowFlag is true.
* @param boolean $nowFlag Connect to database now
* @return boolean Success
public static function dbConnect($nowFlag = false)
Zend_Loader::loadClass('Zend_Db');
Zend_Loader::loadClass('Zend_Db_Table');
// Process configuration file.
$config = new Zend_Config_Ini(self::$dbConfigFile, self::CONFIG_SEC_DATABASE);
if (!isset ($config->type)) return false;
if (isset ($config->host)) $options['host'] = $config->host;
if (isset ($config->port)) $options['port'] = $config->port;
if (!isset ($config->dbname)) return false;
$options['dbname'] = $config->dbname;
if (isset ($config->username)) $options['username'] = $config->username;
if (isset ($config->password)) $options['password'] = $config->password;
self::$db = Zend_Db::factory($type, $options);
if ($nowFlag) self::$db->getConnection();
Zend_Db_Table::setDefaultAdapter(self::$db);
catch (Zend_Exception $e)
self::$logger->err(__METHOD__ . '[' . __LINE__ . '] ' . 'Exception from ' . get_class($e) . ': ' . $e->getMessage() . '.');
* @param string $filename
* @return mixed Filename without extension, or false if wrong file extension
if ($dotPos === false) return '';
$fileExt = substr($filename, $dotPos + 1);
if ($fileExt != $ext) return false;
return substr($filename, 0, $dotPos);
* Display W3C bricks for valid X/HTML, CSS, and WCAG.
* The files valid-xhtml11.png, valid-html401.png, and vcss.png (all
* available from w3.org) must be in brickDir.
* @param boolean $link Link to validator pages (unless SSL)
// If SSL, disable links because there will be no referrer.
if (isset ($_SERVER['HTTPS'])) $link = false;
if ($link) echo '<a href = "http://www.citadelnetwork.com/open/php/cnzframework/">';
echo '<img alt = "[CNZ Framework]" src = "' . self::$brickDir . 'cnzframework.png" style = "border-style:none; height:31px; margin-right:5px; width:88px;"/>';
if (self::$contentType == self::CONTENT_TYPE_XHTML)
if ($link) echo '<a href = "http://validator.w3.org/check?uri=referer">';
if (self::$transitionalFlag) echo '<img alt = "[Valid XHTML 1.0]" src = "' . self::$brickDir . 'valid-xhtml10.png" style = "border-style:none; height:31px; width:88px;"/>';
else echo '<img alt = "[Valid XHTML 1.1]" src = "' . self::$brickDir . 'valid-xhtml11.png" style = "border-style:none; height:31px; width:88px;"/>';
if ($link) echo '<a href = "http://validator.w3.org/check?uri=referer">';
echo '<img alt = "[Valid HTML 4.01 Strict]" src = "' . self::$brickDir . 'valid-html401.png" style = "border-style:none; height:31px; width:88px;"/>';
if ($link) echo '<a href = "http://jigsaw.w3.org/css-validator/check/referer">';
echo '<img alt = "[Valid CSS]" src = "' . self::$brickDir . 'vcss.png" style = "border-style:none; height:31px; width:88px;"/>';
if (!empty(self::$wcagLevel))
if ($link) echo '<a href = "http://www.w3.org/WAI/WCAG1', self::$wcagLevel, '-Conformance">';
echo '<img alt = "[WCAG Level ', self::$wcagLevel, ' Conformance]" src = "' . self::$brickDir . 'wcag1', self::$wcagLevel, '.gif" style = "border-style:none; height:31px; width:88px;"/>';
* Determine the current document directory. This is necessary for use
* with mod_rewrite, when the script directory cannot be relied on.
* @param relative Relative (to web doc root) flag
* @return string Root URL
public static function docDir($relative = false)
if (isset ($_SERVER['REDIRECT_URL']))
$dir = $_SERVER['DOCUMENT_ROOT'] . $_SERVER['REDIRECT_URL'];
if (substr($dir, - 1) != '/') $dir = dirname($dir);
if ($relative) $dir = substr($dir, strlen($_SERVER['DOCUMENT_ROOT']));
* Extrace the the extension from a file name.
* @param string $filename
* @return string File extension
if ($dotPos === false) return '';
return substr($filename, $dotPos + 1);
* Convert an absolute filesystem pathname to URI.
* @param string filepath Filesystem pathname
* @return string URI of file, or NULL on error.
// Verify that filepath is within web document tree.
if (strncmp($filepath, $_SERVER['DOCUMENT_ROOT'], strlen($_SERVER['DOCUMENT_ROOT'])) != 0)
$uri .= substr($filepath, strlen($_SERVER['DOCUMENT_ROOT']));
* Decrement the indentation level.
* @param int $n Number of levels to decrement.
if (self::$indentLevel <= 0) return;
self::$indentLevel -= $n;
* Generate the indentation for display.
return str_pad('', self::$indentLevel, self::$indentString);
* Increment the indentation level.
* @param int $n Number of levels to increment.
self::$indentLevel += $n;
* Initialize the application.
* This method can optionally establish a connection to a database.
* For security reasons, the database configuration is expected to be
* in a separate file, but this is not required. The default
* configuration files are <kbd>html.ini</kbd> and
* <kbd>database.ini</kbd>, both in the default configuration
* directory <kbd>cfg</kbd> adjacent to the web document root.
* domain Site domain (required)
* sslDomain Site SSL domain (default none)
* charSets Character set list (default utf-8)
* languages Language list (default en-us)
* transitional Transitional flag (default no)
* indent Indent string (default \t)
* wcagLevel WCAG Conformance (default none)
* brickDir Brick directory (default /slib/image/brick)
* buttonDir Button directory (default /slib/image/button)
* logDir Log directory (default log)
* tmpDir Temporary directory (default tmp)
* uploadDir Upload tmp directory (default upload)
* logFile HTML log File (default html.log)
* logLevel HTML log level (default info)
* phpLogFile PHP log File (default unchanged)
* phpLoglevel PHP log Level (default unchanged)
* @param string $configFile Configuration file
* @param string $dbConfigFile Database configuration file
* @param boolean $dbConnectFlag Connect to database now
public static function init($configFile = NULL, $dbConfigFile = NULL, $dbConnectFlag = false)
if (is_file($_SERVER['DOCUMENT_ROOT'] . '/' . self::DEFAULT_CFG_FILE)) $configFile = $_SERVER['DOCUMENT_ROOT'] . '/' . self::DEFAULT_CFG_FILE;
self::$htmlConfigFile = $configFile;
// Process configuration file.
$config = new Zend_Config_Ini(self::$htmlConfigFile, self::CONFIG_SEC_HTML);
if (isset ($config->domain)) self::$domain = $config->domain;
if (isset ($config->sslDomain)) self::$sslDomain = $config->sslDomain;
if (isset ($config->charSets)) self::$charSetArray = self::listToArray($config->charSets);
if (isset ($config->languages)) self::$languageArray = self::listToArray($config->languages);
if (isset ($config->brickDir)) self::$brickDir = $config->brickDir;
if (isset ($config->buttonDir)) self::$buttonDir = $config->buttonDir;
if (isset ($config->indent)) self::$indentString = $config->indent;
if (isset ($config->wcagLevel)) self::$wcagLevel = $config->wcagLevel;
if (isset ($config->tmpDir)) self::$tmpDir = $config->tmpDir;
if (substr(self::$tmpDir, 0, 1) != '/') self::$tmpDir = $_SERVER['DOCUMENT_ROOT'] . '/../' . self::$tmpDir;
if (isset ($config->uploadDir)) self::$uploadDir = $config->uploadDir . '/';
if (substr(self::$uploadDir, 0, 1) != '/') self::$uploadDir = $_SERVER['DOCUMENT_ROOT'] . '/../' . self::$uploadDir;
if (isset ($config->transitional)) self::$transitionalFlag = self::configFlag($config->transitional);
if (isset ($config->phpLogLevel))
self::$phpLogLevel = $config->phpLoglevel;
if (!defined('E_RECOVERABLE_ERROR'))
// For backward compatibility (pre-5.2)
define('E_RECOVERABLE_ERROR', E_USER_NOTICE);
* eval() is being intentionally avoided, but Zend_Config_Ini
* apparently automatically evaluates some things if the
* setting is not in quotes. Hence the double cases.
switch ($config->errorLevel)
case 'E_RECOVERABLE_ERROR':
case E_RECOVERABLE_ERROR:
$er |= E_RECOVERABLE_ERROR;
case 'E_COMPILE_WARNING':
$er |= E_COMPILE_WARNING;
trigger_error('Configured errorLevel ' . $config->errorLevel . ' is invalid.', E_USER_ERROR);
// This will be logged after logging is initialized.
if (isset ($config->logDir)) self::$logDir = $config->logDir;
if (substr(self::$logDir, 0, 1) != '/') self::$logDir = $_SERVER['DOCUMENT_ROOT'] . '/../' . self::$logDir;
if (isset ($config->logFile)) self::$logFile = $config->logFile;
if (isset ($config->phpLogFile)) self::$phpLogFile = $config->phpLogFile;
if (isset ($config->logLevel))
switch (strtolower($config->logLevel))
self::$logLevel = Zend_Log::EMERG;
self::$logLevel = Zend_Log::ALERT;
self::$logLevel = Zend_Log::CRIT;
self::$logLevel = Zend_Log::ERR;
self::$logLevel = Zend_Log::WARN;
self::$logLevel = Zend_Log::NOTICE;
self::$logLevel = Zend_Log::INFO;
self::$logLevel = Zend_Log::DEBUG;
trigger_error('Configured logLevel ' . $config->logLevel . ' is invalid.', E_USER_ERROR);
if (!empty(self::$phpLogFile))
if (ini_set('error_log', self::$logDir . self::$phpLogFile) === false)
trigger_error('Error setting error_log to ' . $logDirAbsolute . self::PHP_LOG_FILE. '.', E_USER_ERROR);
trigger_error('logDir ' . self::$logDir . ' does note exist.', E_USER_ERROR);
$logWriter = new Zend_Log_Writer_Stream(self::$logDir . self::$logFile);
self::$logger = new Zend_Log($logWriter);
$logFilter = new Zend_Log_Filter_Priority(self::$logLevel);
self::$logger->addFilter($logFilter);
self::$logger->debug(__METHOD__ . '[' . __LINE__ . '] ' . 'Logging initialized at level ' . self::$logLevel . '.');
if (isset ($oldEr)) self::$logger->info( __METHOD__ . '[' . __LINE__ . '] ' . 'Error reporting changed from ' . $oldEr . ' to ' . $er . '.');
// Determine preferred content type.
// If a W3C validator, use XHTML,
// else check HTTP_ACCEPT to see if the browser prefers XHTML.
if (strncmp($_SERVER['HTTP_USER_AGENT'], 'W3C_Validator', 13) == 0 || strpos($_SERVER['HTTP_USER_AGENT'], 'W3C_CSS_Validator') !== false)
self::$contentType = self::CONTENT_TYPE_XHTML;
else if (isset ($_SERVER['HTTP_ACCEPT']))
$acceptArray = self::parseAcceptHeader($_SERVER['HTTP_ACCEPT']);
if (isset ($acceptArray[self::CONTENT_TYPE_XHTML]))
$xhtmlQ = $acceptArray[self::CONTENT_TYPE_XHTML];
if (isset ($acceptArray[self::CONTENT_TYPE_HTML]))
$htmlQ = $acceptArray[self::CONTENT_TYPE_HTML];
if ($xhtmlQ > 0 && $xhtmlQ >= $htmlQ)
self::$contentType = self::CONTENT_TYPE_XHTML;
// Determine preferred charset.
if (isset ($_SERVER['HTTP_ACCEPT_CHARSET']))
$acceptArray = self::parseAcceptHeader($_SERVER['HTTP_ACCEPT_CHARSET']);
foreach (self::$charSetArray as $charSet)
if (isset ($acceptArray[$charSet]))
if ($acceptArray[$charSet] > $q)
$q = $acceptArray[$charSet];
if (isset ($l)) self::$charSet = $l;
else self::$charSet = self::$charSetArray[0];
// Determine preferred language.
if (isset ($_SERVER['HTTP_ACCEPT_LANGUAGE']))
$acceptArray = self::parseAcceptHeader($_SERVER['HTTP_ACCEPT_LANGUAGE']);
foreach (self::$languageArray as $language)
if (isset ($acceptArray[$language]))
if ($acceptArray[$language] > $q)
$q = $acceptArray[$language];
if (isset ($l)) self::$language = $l;
else self::$language = self::$languageArray[0];
// Set up for the preferred content type.
// See http://www.w3.org/QA/2002/04/valid-dtd-list.html.
$charSet = self::$charSet; // for use in heredoc
$language = self::$language;
switch (self::$contentType)
case self::CONTENT_TYPE_XHTML:
self::$javascriptType = self::JAVASCRIPT_TYPE_XHTML;
if (self::$transitionalFlag)
<? xml version = "1.0" encoding = " $charSet" ?>
<! DOCTYPE html PUBLIC "-// W3C// DTD XHTML 1.0 Transitional// EN" " http:// www. w3. org/ TR/ xhtml1/ DTD/ xhtml1- transitional. dtd">
< html xmlns = " http:// www. w3. org/1999/ xhtml" xml: lang = " $language">
<? xml version = "1.0" encoding = " $charSet" ?>
<! DOCTYPE html PUBLIC "-// W3C// DTD XHTML 1.1// EN" " http:// www. w3. org/ TR/ xhtml11/ DTD/ xhtml11. dtd">
< html xmlns = " http:// www. w3. org/1999/ xhtml" version = "-// W3C// DTD XHTML 1.1// EN" xml: lang = " $language">
case self::CONTENT_TYPE_HTML:
if (!ob_start(array('Cnz_Html', 'xhtmlToHtml')))
if (self::$transitionalFlag)
<! DOCTYPE html PUBLIC "-// W3C// DTD HTML 4.01 Transitional// EN" " http:// www. w3. org/ TR/ html4/ loose. dtd">
< html lang = " $language">
<! DOCTYPE HTML PUBLIC "-// W3C// DTD HTML 4.01// EN" " http:// www. w3. org/ TR/ html4/ strict. dtd">
< html lang = " $language">
header('Content-Type: ' . self::$contentType . '; charset=' . self::$charSet);
header('Content-Language: ' . self::$language);
header('Content-Script-Type: ' . self::$javascriptType);
header('Content-Style-Type: text/css');
header('Vary: Accept,Accept-Charset,Accept-Language');
if (is_file($_SERVER['DOCUMENT_ROOT'] . '/' . self::DEFAULT_DBCFG_FILE)) $dbConfigFile = $_SERVER['DOCUMENT_ROOT'] . '/' . self::DEFAULT_DBCFG_FILE;
self::$dbConfigFile = $dbConfigFile;
if (self::$dbConfigFile) self::dbConnect($dbConnectFlag);
* This function converts a list to an array and appends the results to
if (empty($list)) return;
$b = self::listToArray($list);
* Convert a list of the form key:val,key:val to an associative array.
* If a list item has more then 2 fields, the value is set to an array
* of all the fields beyond the key.
* @return array List as assocative array.
$listPattern = '/(?<!\\\\)' . self::$listDelimiter . '/';
$fieldPattern = '/(?<!\\\\)' . self::$fieldDelimiter . '/';
$a = preg_split($listPattern, $list);
foreach ($value as $k => $v)
$value[$k] = str_replace('\\' . self::$listDelimiter, self::$listDelimiter, str_replace('\\' . self::$fieldDelimiter, self::$fieldDelimiter, trim($v)));
$value = str_replace('\\' . self::$listDelimiter, self::$listDelimiter, str_replace('\\' . self::$fieldDelimiter, self::$fieldDelimiter, trim($b[1])));
$key = str_replace('\\' . self::$listDelimiter, self::$listDelimiter, str_replace('\\' . self::$fieldDelimiter, self::$fieldDelimiter, trim($b[0])));
* Load class, create object, then display with a single statement.
* @param array $options Common options
* @param string $style Value for outermost style attribute
* @return object Created object of type $className
public static function loadAndDisplay($className, $options = array(), $style = NULL)
Zend_Loader::loadClass($className);
$object = new $className($options);
$object->display($style);
* See {@link http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html}
* for details on the format of Accept headers.
* @param string $header Header
* @return array Header as an associative array of form type => Q value
for ($i = 0; $i < $n; $i++ )
// If no Q value specified, default is 1.0.
if (count($t) == 1) $t[] = (float) 1.0;
$aa[$t[0]] = (float) $t[1];
* Generate the root URI (without trailing /).
* @return string Root URL
if (self::isSsl()) return 'https://' . self::$sslDomain;
else return 'http://' . self::$domain;
* Strips short-hand end-tags from XHTML to make valid HTML.
* This method is public for use by output buffering functions. It
* would not be called directly by the application.
* @param string $buffer Output buffer
* @return string Modified output buffer
return preg_replace('!\s*/>!', '>', $buffer);
/* Methods ===========================================================*/
* This is a utility class.
private function __construct()
|