} else {
$this->_agent = $userAgent;
}
- $this->_lowerAgent = String::lower($this->_agent);
+ $this->_lowerAgent = Horde_String::lower($this->_agent);
// Set our accept string.
if (is_null($accept)) {
if (isset($_SERVER['HTTP_ACCEPT'])) {
- $this->_accept = String::lower(trim($_SERVER['HTTP_ACCEPT']));
+ $this->_accept = Horde_String::lower(trim($_SERVER['HTTP_ACCEPT']));
}
} else {
- $this->_accept = String::lower($accept);
+ $this->_accept = Horde_String::lower($accept);
}
// Check for UTF support.
if (isset($_SERVER['HTTP_ACCEPT_CHARSET'])) {
- $this->setFeature('utf', strpos(String::lower($_SERVER['HTTP_ACCEPT_CHARSET']), 'utf') !== false);
+ $this->setFeature('utf', strpos(Horde_String::lower($_SERVER['HTTP_ACCEPT_CHARSET']), 'utf') !== false);
}
if (empty($this->_agent)) {
return true;
} elseif (($error == UPLOAD_ERR_INI_SIZE) ||
($error == UPLOAD_ERR_FORM_SIZE)) {
- return PEAR::raiseError(sprintf(_("There was a problem with the file upload: The %s was larger than the maximum allowed size (%d bytes)."), $name, min($uploadSize, Util::getFormData('MAX_FILE_SIZE'))), $error);
+ return PEAR::raiseError(sprintf(_("There was a problem with the file upload: The %s was larger than the maximum allowed size (%d bytes)."), $name, min($uploadSize, Horde_Util::getFormData('MAX_FILE_SIZE'))), $error);
} elseif ($error == UPLOAD_ERR_PARTIAL) {
return PEAR::raiseError(sprintf(_("There was a problem with the file upload: The %s was only partially uploaded."), $name), $error);
}
*/
public function isViewable($mimetype)
{
- $mimetype = String::lower($mimetype);
+ $mimetype = Horde_String::lower($mimetype);
list($type, $subtype) = explode('/', $mimetype);
if (!empty($this->_accept)) {
if (!empty($params['dir']) && @is_dir($params['dir'])) {
$this->_dir = $params['dir'];
} else {
- require_once 'Horde/Util.php';
- $this->_dir = Util::getTempDir();
+ $this->_dir = Horde_Util::getTempDir();
}
foreach (array('prefix', 'sub') as $val) {
*/
public function set($key, $data, $lifetime = null)
{
- require_once 'Horde/Util.php';
$filename = $this->_keyToFile($key, true);
- $tmp_file = Util::getTempFile('HordeCache', true, $this->_dir);
+ $tmp_file = Horde_Util::getTempFile('HordeCache', true, $this->_dir);
if (isset($this->_params['umask'])) {
chmod($tmp_file, 0666 & ~$this->_params['umask']);
}
return true;
}
- $result = Util::assertDriverConfig($this->_params, array('phptype'),
- 'cache SQL', array('driver' => 'cache'));
+ $result = Horde_Util::assertDriverConfig($this->_params, array('phptype'), 'cache SQL', array('driver' => 'cache'));
if (is_a($result, 'PEAR_Error')) {
throw new Horde_Exception($result->getMessage());
}
protected function _createTempFile($descrip = 'horde-crypt',
$delete = true)
{
- return Util::getTempFile($descrip, $delete, $this->_tempdir, true);
+ return Horde_Util::getTempFile($descrip, $delete, $this->_tempdir, true);
}
}
*/
protected function __construct($params = array())
{
- $this->_tempdir = Util::createTempDir(true, $params['temp']);
+ $this->_tempdir = Horde_Util::createTempDir(true, $params['temp']);
if (empty($params['program'])) {
Horde::fatal(new Horde_Exception('The location of the GnuPG binary must be given to the Horde_Crypt_Pgp:: class.'), __FILE__, __LINE__);
/* Headers are prefaced with a ':' as the first character on the
line. */
if (strpos($line, ':') === 0) {
- $lowerLine = String::lower($line);
+ $lowerLine = Horde_String::lower($line);
/* If we have a key (rather than a signature block), get the
key's ID */
*/
protected function _pgpPrettyKeyFormatter(&$s, $k, $m)
{
- $s .= ':' . str_repeat(' ', $m - String::length($s));
+ $s .= ':' . str_repeat(' ', $m - Horde_String::length($s));
}
/**
if ($errno == 0) {
throw new Horde_Exception(_("Connection refused to the public keyserver."), 'horde.error');
} else {
- throw new Horde_Exception(sprintf(_("Connection refused to the public keyserver. Reason: %s (%s)"), String::convertCharset($errstr, NLS::getExternalCharset()), $errno), 'horde.error');
+ throw new Horde_Exception(sprintf(_("Connection refused to the public keyserver. Reason: %s (%s)"), Horde_String::convertCharset($errstr, NLS::getExternalCharset()), $errno), 'horde.error');
}
}
*/
protected function _createKeyring($type = 'public')
{
- $type = String::lower($type);
+ $type = Horde_String::lower($type);
if ($type === 'public') {
if (empty($this->_publicKeyring)) {
*/
protected function _putInKeyring($keys = array(), $type = 'public')
{
- $type = String::lower($type);
+ $type = Horde_String::lower($type);
if (!is_array($keys)) {
$keys = array($keys);
$pgp_sign->setType('application/pgp-signature');
$pgp_sign->setCharset($charset);
$pgp_sign->setDisposition('inline');
- $pgp_sign->setDescription(String::convertCharset(_("PGP Digital Signature"), NLS::getCharset(), $charset));
+ $pgp_sign->setDescription(Horde_String::convertCharset(_("PGP Digital Signature"), NLS::getCharset(), $charset));
$pgp_sign->setContents($msg_sign);
/* Get the algorithim information from the signature. Since we are
$part->setType('multipart/encrypted');
$part->setCharset($charset);
$part->setContentTypeParameter('protocol', 'application/pgp-encrypted');
- $part->setDescription(String::convertCharset(_("PGP Encrypted Data"), NLS::getCharset(), $charset));
+ $part->setDescription(Horde_String::convertCharset(_("PGP Encrypted Data"), NLS::getCharset(), $charset));
$part->setContents('This message is in MIME format and has been PGP encrypted.' . "\n");
$part1 = new Horde_Mime_Part();
$charset = NLS::getEmailCharset();
$part->setCharset($charset);
- $part->setDescription(String::convertCharset(_("PGP Signed/Encrypted Data"), NLS::getCharset(), $charset));
+ $part->setDescription(Horde_String::convertCharset(_("PGP Signed/Encrypted Data"), NLS::getCharset(), $charset));
return $part;
}
$part = new Horde_Mime_Part();
$part->setType('application/pgp-keys');
$part->setCharset($charset);
- $part->setDescription(String::convertCharset(_("PGP Public Key"), NLS::getCharset(), $charset));
+ $part->setDescription(Horde_String::convertCharset(_("PGP Public Key"), NLS::getCharset(), $charset));
$part->setContents($key);
return $part;
$msg = new Horde_Mime_Part();
$msg->setCharset($charset);
- $msg->setDescription(String::convertCharset(_("S/MIME Encrypted Message"), NLS::getCharset(), $charset));
+ $msg->setDescription(Horde_String::convertCharset(_("S/MIME Encrypted Message"), NLS::getCharset(), $charset));
$msg->setDisposition('inline');
$msg->setType('application/pkcs7-mime');
$msg->setContentTypeParameter('smime-type', 'enveloped-data');
$text .= "<strong>" . _("Public Key Info") . ":</strong>\n";
$text .= sprintf(" %s: %s\n", _("Public Key Algorithm"), $certificate['subjectPublicKeyInfo']['algorithm']);
if ($certificate['subjectPublicKeyInfo']['algorithm'] == 'rsaEncryption') {
- if (Util::extensionExists('bcmath')) {
+ if (Horde_Util::extensionExists('bcmath')) {
$modulus = $certificate['subjectPublicKeyInfo']['subjectPublicKey']['modulus'];
$modulus_hex = '';
while ($modulus != '0') {
$text .= sprintf(" %s: %d\n", _("Serial Number"), $certificate['serialNumber']);
foreach ($cert_details['fingerprints'] as $hash => $fingerprint) {
- $label = sprintf(_("%s Fingerprint"), String::upper($hash));
+ $label = sprintf(_("%s Fingerprint"), Horde_String::upper($hash));
$fingerprint_str = '';
for ($i = 0; $i < strlen($fingerprint); $i += 2) {
$fingerprint_str .= substr($fingerprint, $i, 2) . ':';
if (($val[11] == '-') || ($val[9] == '+')) {
// handle time zone offset here
$seconds = 0;
- } elseif (String::upper($val[11]) == 'Z') {
+ } elseif (Horde_String::upper($val[11]) == 'Z') {
$seconds = 0;
} else {
$seconds = substr($val, 10, 2);
}
} else {
/* Method works for arbitrary length integers */
- if (Util::extensionExists('bcmath')) {
+ if (Horde_Util::extensionExists('bcmath')) {
for ($i = 0; $i < strlen($integer_data); $i++) {
$value = bcadd(bcmul($value, 256), ord($integer_data[$i]));
}
*/
public function checkForOpenSSL()
{
- if (!Util::extensionExists('openssl')) {
+ if (!Horde_Util::extensionExists('openssl')) {
throw new Horde_Exception(_("The openssl module is required for the Horde_Crypt_Smime:: class."));
}
}
continue;
}
list($kind, $value) = explode(':', $name, 2);
- if (String::lower($kind) == 'email') {
+ if (Horde_String::lower($kind) == 'email') {
return $value;
}
}
$pgp = Horde_Crypt::factory('Pgp', array(
'program' => '/usr/bin/gpg',
- 'temp' => Util::getTempDir()
+ 'temp' => Horde_Util::getTempDir()
));
$pubkey = file_get_contents($filedir . '/fixtures/pgp_public.asc');
require 'Horde/Util.php';
require dirname(__FILE__) . '/../../../lib/Horde/Crypt.php';
-$smime = Horde_Crypt::factory('Smime', array('temp' => Util::getTempDir()));
+$smime = Horde_Crypt::factory('Smime', array('temp' => Horde_Util::getTempDir()));
$parts = explode(';', $rrule);
foreach ($parts as $part) {
list($key, $value) = explode('=', $part, 2);
- $rdata[String::upper($key)] = $value;
+ $rdata[Horde_String::upper($key)] = $value;
}
if (isset($rdata['FREQ'])) {
// Always default the recurInterval to 1.
$this->setRecurInterval(isset($rdata['INTERVAL']) ? $rdata['INTERVAL'] : 1);
- switch (String::upper($rdata['FREQ'])) {
+ switch (Horde_String::upper($rdata['FREQ'])) {
case 'DAILY':
$this->setRecurType(self::RECUR_DAILY);
break;
{
protected function setUp()
{
- require_once 'Horde/String.php';
- String::setDefaultCharset('UTF-8');
+ Horde_String::setDefaultCharset('UTF-8');
$this->ical = new Horde_iCalendar();
}
} elseif (isset($GLOBALS['language'])) {
$language = explode('_', $GLOBALS['language']);
if (count($language) > 1) {
- $country = String::lower($language[1]);
+ $country = Horde_String::lower($language[1]);
if ($country == $language[0]) {
$language = $language[0];
} else {
if (isset($criteria['field'])) {
$rhs = isset($criteria['test']) ? $criteria['test'] : '';
/* Keep this in for reference as we did not really test servers with different encoding yet */
- // require_once 'Horde/String.php';
// require_once 'Horde/NLS.php';
- //$rhs = String::convertCharset($criteria['test'], NLS::getCharset(), $this->params['charset']);
+ //$rhs = Horde_String::convertCharset($criteria['test'], NLS::getCharset(), $this->params['charset']);
switch ($criteria['op']) {
case '=':
$op = 'equals';
function getMessageHeader($uid, $peek_for_body = true)
{
$ret = $this->_imap->cmdUidFetch($uid, 'BODY[HEADER]');
- if (String::upper($ret['RESPONSE']['CODE']) != 'OK') {
+ if (Horde_String::upper($ret['RESPONSE']['CODE']) != 'OK') {
return PEAR::raiseError(sprintf(_("Failed fetching headers of IMAP message %s. Error was %s"),
$uid,
$ret['RESPONSE']['CODE'] . ', ' . $ret['RESPONSE']['STR_CODE']));
function getMessageBody($uid)
{
$ret = $this->_imap->cmdUidFetch($uid, 'BODY[TEXT]');
- if (String::upper($ret['RESPONSE']['CODE']) != 'OK') {
+ if (Horde_String::upper($ret['RESPONSE']['CODE']) != 'OK') {
return PEAR::raiseError(sprintf(_("Failed fetching body of IMAP message %s. Error was %s"),
$uid,
$ret['RESPONSE']['CODE'] . ', ' . $ret['RESPONSE']['STR_CODE']));
function getMessage($uid)
{
$ret = $this->_imap->cmdUidFetch($uid, 'RFC822');
- if (String::upper($ret['RESPONSE']['CODE']) != 'OK') {
+ if (Horde_String::upper($ret['RESPONSE']['CODE']) != 'OK') {
return PEAR::raiseError(sprintf(_("Failed fetching IMAP message %s. Error was %s"),
$uid,
$ret['RESPONSE']['CODE'] . ', ' . $ret['RESPONSE']['STR_CODE']));
function copyMessage($uid, $new_folder)
{
$ret = $this->_imap->cmdUidCopy($uid, $new_folder);
- if (String::upper($ret['RESPONSE']['CODE']) != 'OK') {
+ if (Horde_String::upper($ret['RESPONSE']['CODE']) != 'OK') {
return PEAR::raiseError(sprintf(_("IMAP error. Message: %s. Error: %s"),
$uid,
$ret['RESPONSE']['CODE'] . ', ' . $ret['RESPONSE']['STR_CODE']));
foreach ($uids as $uid) {
$ret = $this->_imap->cmdUidStore($uid, '+FLAGS.SILENT', '\Deleted');
- if (String::upper($ret['RESPONSE']['CODE']) != 'OK') {
+ if (Horde_String::upper($ret['RESPONSE']['CODE']) != 'OK') {
return PEAR::raiseError(sprintf(_("IMAP error. Message: %s. Error: %s"),
$uid,
$ret['RESPONSE']['CODE'] . ', ' . $ret['RESPONSE']['STR_CODE']));
function undeleteMessages($uid)
{
$ret = $this->_imap->cmdUidStore($uid, '-FLAGS.SILENT', '\Deleted');
- if (String::upper($ret['RESPONSE']['CODE']) != 'OK') {
+ if (Horde_String::upper($ret['RESPONSE']['CODE']) != 'OK') {
return PEAR::raiseError(sprintf(_("IMAP error. Message: %s. Error: %s"),
$uid,
$ret['RESPONSE']['CODE'] . ', ' . $ret['RESPONSE']['STR_CODE']));
require_once 'Horde/NLS.php';
$charset = NLS::getCharset();
}
- $charset = String::lower($charset);
+ $charset = Horde_String::lower($charset);
if (($charset == 'us-ascii') || !self::is8bit($text, $charset)) {
return $text;
(($text[$i + 1] == "\n") || ($text[$i + 1] == "\r"))) ||
(($ascii < 32) || ($ascii > 126) || ($ascii === 61))) {
$char_len = 3;
- $char = '=' . String::upper(sprintf('%02s', dechex($ascii)));
+ $char = '=' . Horde_String::upper(sprintf('%02s', dechex($ascii)));
} else {
$char_len = 1;
}
case 'Q':
case 'q':
$decoded = preg_replace('/=([0-9a-f]{2})/ie', 'chr(0x\1)', str_replace('_', ' ', $encoded_text));
- $decoded = String::convertCharset($decoded, $charset, $to_charset);
+ $decoded = Horde_String::convertCharset($decoded, $charset, $to_charset);
break;
case 'B':
case 'b':
- $decoded = String::convertCharset(base64_decode($encoded_text), $charset, $to_charset);
+ $decoded = Horde_String::convertCharset(base64_decode($encoded_text), $charset, $to_charset);
break;
default:
$pre_len = strlen($name) + 2;
if (self::is8bit($val, $charset)) {
- $string = String::lower($charset) . '\'' . (empty($opts['lang']) ? '' : String::lower($opts['lang'])) . '\'' . rawurlencode($val);
+ $string = Horde_String::lower($charset) . '\'' . (empty($opts['lang']) ? '' : Horde_String::lower($opts['lang'])) . '\'' . rawurlencode($val);
$encode = true;
/* Account for trailing '*'. */
++$pre_len;
if (is_array($data)) {
// Use dummy base values
- $ret['val'] = (String::lower($type) == 'content-type')
+ $ret['val'] = (Horde_String::lower($type) == 'content-type')
? 'text/plain'
: 'attachment';
$params = $data;
/* Ignore language. */
$quote = strpos($val, "'", $quote + 1);
substr($val, $quote + 1);
- $ret['params'][$name] = String::convertCharset(urldecode(substr($val, $quote + 1)), $orig_charset, $charset);
+ $ret['params'][$name] = Horde_String::convertCharset(urldecode(substr($val, $quote + 1)), $orig_charset, $charset);
}
/* MIME parameters are supposed to be encoded via RFC 2231, but many
$host = ltrim($host, '@');
if ((!isset($opts['idn']) || !$opts['idn']) &&
(stripos($host, 'xn--') === 0) &&
- Util::extensionExists('idn')) {
- $host = String::convertCharset(idn_to_utf8($host), 'UTF-8');
+ Horde_Util::extensionExists('idn')) {
+ $host = Horde_String::convertCharset(idn_to_utf8($host), 'UTF-8');
}
$address .= self::encode($mailbox, 'address') . '@' . $host;
foreach ($addresses as $addr) {
$val = self::addrObject2String($addr, $opts);
if (!empty($val)) {
- $addrList[String::lower(self::bareAddress($val))] = $val;
+ $addrList[Horde_String::lower(self::bareAddress($val))] = $val;
}
}
*/
public function addHeader($header, $value, $options = array())
{
- require_once 'Horde/String.php';
-
$header = trim($header);
- $lcHeader = String::lower($header);
+ $lcHeader = Horde_String::lower($header);
if (!isset($this->_headers[$lcHeader])) {
$this->_headers[$lcHeader] = array();
*/
public function removeHeader($header)
{
- require_once 'Horde/String.php';
- unset($this->_headers[String::lower(trim($header))]);
+ unset($this->_headers[Horde_String::lower(trim($header))]);
}
/**
*/
public function setValue($header, $value, $options = array())
{
- require_once 'Horde/String.php';
-
- if (isset($this->_headers[String::lower($header)])) {
+ if (isset($this->_headers[Horde_String::lower($header)])) {
$this->addHeader($header, $value, $decode);
return true;
}
*/
public function getString($header)
{
- require_once 'Horde/String.php';
-
- $lcHeader = String::lower($header);
+ $lcHeader = Horde_String::lower($header);
return (isset($this->_headers[$lcHeader]))
? $this->_headers[$lcHeader]['header']
: null;
*/
public function getValue($header)
{
- require_once 'Horde/String.php';
-
$entry = null;
- $header = String::lower($header);
+ $header = Horde_String::lower($header);
if (isset($this->_headers[$header])) {
$ptr = &$this->_headers[$header];
$mime = self::mimeParamFields();
$to_process = array();
- require_once 'Horde/String.php';
-
foreach (explode("\n", $text) as $val) {
$val = rtrim($val);
if (empty($val)) {
$currtext .= ' ' . ltrim($val);
} else {
if (!is_null($currheader)) {
- if (in_array(String::lower($currheader), $mime)) {
+ if (in_array(Horde_String::lower($currheader), $mime)) {
$res = Horde_Mime::decodeParam($currheader, $currtext);
$to_process[] = array($currheader, $res['val'], array('decode' => true, 'params' => $res['params']));
} else {
reset($to_process);
while (list(,$val) = each($to_process)) {
if ($eightbit_check && Horde_Mime::is8bit($val[1])) {
- $val[1] = String::convertCharset($val[1], self::$defaultCharset);
+ $val[1] = Horde_String::convertCharset($val[1], self::$defaultCharset);
}
$headers->addHeader($val[0], $val[1], $val[2]);
}
<?php
-
-require_once 'Horde/Util.php';
-
/**
* The Horde_Mime_Magic:: class provides an interface to determine a MIME type
* for various content, if it provided with different levels of information.
return 'application/octet-stream';
}
- $ext = String::lower($ext);
+ $ext = Horde_String::lower($ext);
$map = self::_getMimeExtensionMap();
$pos = 0;
static public function analyzeFile($path, $magic_db = null)
{
/* If the PHP Mimetype extension is available, use that. */
- if (Util::extensionExists('fileinfo')) {
+ if (Horde_Util::extensionExists('fileinfo')) {
$res = empty($magic_db)
? @finfo_open(FILEINFO_MIME)
: @finfo_open(FILEINFO_MIME, $magic_db);
}
}
- if (Util::extensionExists('mime_magic')) {
+ if (Horde_Util::extensionExists('mime_magic')) {
return trim(mime_content_type($path));
}
static public function analyzeData($data, $magic_db = null)
{
/* If the PHP Mimetype extension is available, use that. */
- if (Util::extensionExists('fileinfo')) {
+ if (Horde_Util::extensionExists('fileinfo')) {
$res = empty($magic_db)
? @finfo_open(FILEINFO_MIME)
: @finfo_open(FILEINFO_MIME, $magic_db);
<?php
-
-require_once 'Horde/String.php';
-
/**
* The Horde_Mime_Mail:: class wraps around the various MIME library classes
* to provide a simple interface for creating and sending MIME messages.
public function addHeader($header, $value, $charset = 'iso-8859-1',
$overwrite = null)
{
- $lc_header = String::lower($header);
+ $lc_header = Horde_String::lower($header);
/* Only encode value if charset is explicitly specified, otherwise
* the message's charset will be used when building the message. */
{
$value = $this->_headers->getValue($header);
$this->_headers->removeHeader($header);
- if (in_array(String::lower($header), array('to', 'cc', 'bcc'))) {
+ if (in_array(Horde_String::lower($header), array('to', 'cc', 'bcc'))) {
try {
$this->removeRecipients($value);
} catch (Horde_Mime_Exception $e) {}
public function setBody($body, $charset = 'iso-8859-1', $wrap = false)
{
if ($wrap) {
- $body = String::wrap($body, $wrap === true ? 76 : $wrap, "\n");
+ $body = Horde_String::wrap($body, $wrap === true ? 76 : $wrap, "\n");
}
$this->_body = new Horde_Mime_Part();
$this->_body->setType('text/plain');
}
return ($addr_arr[0]['mailbox'] == $ret_arr[0]['mailbox']) &&
- (String::lower($addr_arr[0]['host']) == String::lower($ret_arr[0]['host']));
+ (Horde_String::lower($addr_arr[0]['host']) == Horde_String::lower($ret_arr[0]['host']));
}
/**
<?php
-
-require_once 'Horde/String.php';
-
/**
* The Horde_Mime_Part:: class provides a wrapper around MIME parts and
* methods for dealing with them.
*/
public function setDisposition($disposition)
{
- $disposition = String::lower($disposition);
+ $disposition = Horde_String::lower($disposition);
if (in_array($disposition, array('inline', 'attachment'))) {
$this->_disposition = $disposition;
return;
}
- list($this->_type, $this->_subtype) = explode('/', String::lower($mimetype));
+ list($this->_type, $this->_subtype) = explode('/', Horde_String::lower($mimetype));
/* Known types. */
$known = array(
public function setTransferEncoding($encoding)
{
$known = array('7bit', '8bit', 'binary', 'base64', 'quoted-printable');
- $encoding = String::lower($encoding);
+ $encoding = Horde_String::lower($encoding);
if (in_array($encoding, $known)) {
$this->_transferEncoding = $encoding;
/* Quoted-Printable Encoding: See RFC 2045, section 6.7 */
case 'quoted-printable':
$output = Horde_Mime::quotedPrintableEncode($this->_contents, $eol);
- if (($eollength = String::length($eol)) &&
+ if (($eollength = Horde_String::length($eol)) &&
(substr($output, $eollength * -1) == $eol)) {
return substr($output, 0, $eollength * -1);
}
}
} else {
$bytes = ($this->getPrimaryType() == 'text')
- ? String::length($this->_contents, $this->getCharset())
+ ? Horde_String::length($this->_contents, $this->getCharset())
: strlen($this->_contents);
}
/* Set the default character set. */
if (($data['subtype'] == 'text') &&
(self::$defaultCharset != 'us-ascii') &&
- (String::lower($ob->getCharset()) == 'us-ascii')) {
+ (Horde_String::lower($ob->getCharset()) == 'us-ascii')) {
$ob->setCharset(self::$defaultCharset);
}
// Need Horde headers for CSS tags.
reset($ret);
- $ret[key($ret)]['data'] = Util::bufferOutput('require', $GLOBALS['registry']->get('templates', 'horde') . '/common-header.inc') .
+ $ret[key($ret)]['data'] = Horde_Util::bufferOutput('require', $GLOBALS['registry']->get('templates', 'horde') . '/common-header.inc') .
$ret[key($ret)]['data'] .
- Util::bufferOutput('require', $GLOBALS['registry']->get('templates', 'horde') . '/common-footer.inc');
+ Horde_Util::bufferOutput('require', $GLOBALS['registry']->get('templates', 'horde') . '/common-footer.inc');
return $ret;
}
{
return array(
$this->_mimepart->getMimeId() => array(
- 'data' => String::convertCharset($this->_toHTML(), $this->_mimepart->getCharset()),
+ 'data' => Horde_String::convertCharset($this->_toHTML(), $this->_mimepart->getCharset()),
'status' => array(),
'type' => 'text/html; charset=' . NLS::getCharset()
)
return array(
$this->_mimepart->getMimeId() => array(
- 'data' => String::convertCharset($html['data'], $this->_mimepart->getCharset()),
+ 'data' => Horde_String::convertCharset($html['data'], $this->_mimepart->getCharset()),
'status' => $html['status'],
'type' => 'text/html; charset=' . NLS::getCharset()
)
if (!$inline) {
$temp = array();
foreach ($phish_warning as $val) {
- $temp[] = String::convertCharset($val, NLS::getCharset(), $this->_mimepart->getCharset());
+ $temp[] = Horde_String::convertCharset($val, NLS::getCharset(), $this->_mimepart->getCharset());
}
$warning = $temp;
}
*/
protected function _render()
{
- $has_xslt = Util::extensionExists('xslt');
+ $has_xslt = Horde_Util::extensionExists('xslt');
$has_ssfile = function_exists('domxml_xslt_stylesheet_file');
if (($use_xslt = $has_xslt || $has_ssfile)) {
- $tmpdir = Util::createTempDir(true);
+ $tmpdir = Horde_Util::createTempDir(true);
}
$fnames = array('content.xml', 'styles.xml', 'meta.xml');
}
}
- if (!Util::extensionExists('xslt')) {
+ if (!Horde_Util::extensionExists('xslt')) {
return array();
}
// Need Horde headers for CSS tags.
reset($ret);
- $ret[key($ret)]['data'] = Util::bufferOutput('require', $GLOBALS['registry']->get('templates', 'horde') . '/common-header.inc') .
+ $ret[key($ret)]['data'] = Horde_Util::bufferOutput('require', $GLOBALS['registry']->get('templates', 'horde') . '/common-header.inc') .
$ret[key($ret)]['data'] .
- Util::bufferOutput('require', $GLOBALS['registry']->get('templates', 'horde') . '/common-footer.inc');
+ Horde_Util::bufferOutput('require', $GLOBALS['registry']->get('templates', 'horde') . '/common-footer.inc');
return $ret;
}
*/
protected function _renderInline()
{
- $text = String::convertCharset($this->_mimepart->getContents(), $this->_mimepart->getCharset());
+ $text = Horde_String::convertCharset($this->_mimepart->getContents(), $this->_mimepart->getCharset());
/* Check for 'flowed' text data. */
$data = ($this->_mimepart->getContentTypeParameter('format') == 'flowed')
Text::htmlAllSpaces(sprintf(ngettext("File Count: %d file", "File Count: %d files", $fileCount), $fileCount)) .
"\n\n" .
Text::htmlAllSpaces(
- String::pad(_("File Name"), 50, ' ', STR_PAD_RIGHT) .
- String::pad(_("Attributes"), 10, ' ', STR_PAD_LEFT) .
- String::pad(_("Size"), 10, ' ', STR_PAD_LEFT) .
- String::pad(_("Modified Date"), 19, ' ', STR_PAD_LEFT) .
- String::pad(_("Method"), 10, ' ', STR_PAD_LEFT) .
- String::pad(_("Ratio"), 10, ' ', STR_PAD_LEFT)
+ Horde_String::pad(_("File Name"), 50, ' ', STR_PAD_RIGHT) .
+ Horde_String::pad(_("Attributes"), 10, ' ', STR_PAD_LEFT) .
+ Horde_String::pad(_("Size"), 10, ' ', STR_PAD_LEFT) .
+ Horde_String::pad(_("Modified Date"), 19, ' ', STR_PAD_LEFT) .
+ Horde_String::pad(_("Method"), 10, ' ', STR_PAD_LEFT) .
+ Horde_String::pad(_("Ratio"), 10, ' ', STR_PAD_LEFT)
) . "\n" .
str_repeat('-', 109) . "\n";
: 100 * ($val['csize'] / $val['size']);
$text .= Text::htmlAllSpaces(
- String::pad($val['name'], 50, ' ', STR_PAD_RIGHT) .
- String::pad($val['attr'], 10, ' ', STR_PAD_LEFT) .
- String::pad($val['size'], 10, ' ', STR_PAD_LEFT) .
- String::pad(strftime("%d-%b-%Y %H:%M", $val['date']), 19, ' ', STR_PAD_LEFT) .
- String::pad($val['method'], 10, ' ', STR_PAD_LEFT) .
- String::pad(sprintf("%1.1f%%", $ratio), 10, ' ', STR_PAD_LEFT)
+ Horde_String::pad($val['name'], 50, ' ', STR_PAD_RIGHT) .
+ Horde_String::pad($val['attr'], 10, ' ', STR_PAD_LEFT) .
+ Horde_String::pad($val['size'], 10, ' ', STR_PAD_LEFT) .
+ Horde_String::pad(strftime("%d-%b-%Y %H:%M", $val['date']), 19, ' ', STR_PAD_LEFT) .
+ Horde_String::pad($val['method'], 10, ' ', STR_PAD_LEFT) .
+ Horde_String::pad(sprintf("%1.1f%%", $ratio), 10, ' ', STR_PAD_LEFT)
) . "\n";
}
return false;
}
- $viewer = Horde_Mime_Viewer::factory($this->_mimepart, 'message/' . String::lower($type));
+ $viewer = Horde_Mime_Viewer::factory($this->_mimepart, 'message/' . Horde_String::lower($type));
if ($viewer) {
$viewer->setParams($this->_params);
}
{
return array(
$this->_mimepart->getMimeId() => array(
- 'data' => String::convertCharset($this->_toHTML(), $this->_mimepart->getCharset()),
+ 'data' => Horde_String::convertCharset($this->_toHTML(), $this->_mimepart->getCharset()),
'status' => array(),
'type' => 'text/html; charset=' . NLS::getCharset()
)
// Need Horde headers for CSS tags.
reset($ret);
- $ret[key($ret)]['data'] = Util::bufferOutput('require', $GLOBALS['registry']->get('templates', 'horde') . '/common-header.inc') .
+ $ret[key($ret)]['data'] = Horde_Util::bufferOutput('require', $GLOBALS['registry']->get('templates', 'horde') . '/common-header.inc') .
$ret[key($ret)]['data'] .
- Util::bufferOutput('require', $GLOBALS['registry']->get('templates', 'horde') . '/common-footer.inc');
+ Horde_Util::bufferOutput('require', $GLOBALS['registry']->get('templates', 'horde') . '/common-footer.inc');
return $ret;
}
$ret = $this->_renderInline();
if (!empty($ret)) {
reset($ret);
- $ret[key($ret)]['data'] = Util::bufferOutput('include', $GLOBALS['registry']->get('templates', 'horde') . '/common-header.inc') .
+ $ret[key($ret)]['data'] = Horde_Util::bufferOutput('include', $GLOBALS['registry']->get('templates', 'horde') . '/common-header.inc') .
$ret[key($ret)]['data'] .
- Util::bufferOutput('include', $GLOBALS['registry']->get('templates', 'horde') . '/common-footer.inc');
+ Horde_Util::bufferOutput('include', $GLOBALS['registry']->get('templates', 'horde') . '/common-footer.inc');
}
return $ret;
}
$notification->push(_("There was an error reading the contact data."), 'horde.error');
}
- if (Util::getFormData('import') &&
- Util::getFormData('source') &&
+ if (Horde_Util::getFormData('import') &&
+ Horde_Util::getFormData('source') &&
$registry->hasMethod('contacts/import')) {
- $source = Util::getFormData('source');
+ $source = Horde_Util::getFormData('source');
$count = 0;
foreach ($iCal->getComponents() as $c) {
if (is_a($c, 'Horde_iCalendar_vcard')) {
$photos = $vc->getAllAttributes('PHOTO');
foreach ($photos as $photo) {
if (isset($photo['params']['VALUE']) &&
- String::upper($photo['params']['VALUE']) == 'URI') {
+ Horde_String::upper($photo['params']['VALUE']) == 'URI') {
$html .= $this->_row(_("Photo"),
'<img src="' . htmlspecialchars($photo['value']) . '" />',
false);
} elseif (isset($photo['params']['ENCODING']) &&
- String::upper($photo['params']['ENCODING']) == 'B' &&
+ Horde_String::upper($photo['params']['ENCODING']) == 'B' &&
isset($photo['params']['TYPE']) &&
($GLOBALS['browser']->hasFeature('datauri') === true ||
$GLOBALS['browser']->hasFeature('datauri') >= strlen($photo['value']))) {
}
$types = array();
foreach ($label['params']['TYPE'] as $type) {
- switch(String::upper($type)) {
+ switch(Horde_String::upper($type)) {
case 'HOME':
$types[] = _("Home Address");
break;
}
$types = array();
foreach ($item['params']['TYPE'] as $type) {
- switch(String::upper($type)) {
+ switch(Horde_String::upper($type)) {
case 'HOME':
$types[] = _("Home Address");
break;
$number['params']['TYPE'] = array($number['params']['TYPE']);
}
foreach ($number['params']['TYPE'] as $type) {
- $number['params'][String::upper($type)] = true;
+ $number['params'][Horde_String::upper($type)] = true;
}
}
if (isset($number['params']['FAX'])) {
$address['params']['TYPE'] = array($address['params']['TYPE']);
}
foreach ($address['params']['TYPE'] as $type) {
- $address['params'][String::upper($type)] = true;
+ $address['params'][Horde_String::upper($type)] = true;
}
}
$email = '<a href="';
$registry->hasMethod('contacts/sources')) {
$html .= '<tr><td colspan="2" class="smallheader"><form action="'
. Horde::selfUrl() . '" method="get" name="vcard_import">'
- . Util::formInput();
+ . Horde_Util::formInput();
foreach ($_GET as $key => $val) {
$html .= '<input type="hidden" name="' . htmlspecialchars($key)
. '" value="' . htmlspecialchars($val) . '" />';
return array(
$this->_mimepart->getMimeId() => array(
- 'data' => Util::bufferOutput(array($notification, 'notify'), array('listeners' => 'status')) . $html,
+ 'data' => Horde_Util::bufferOutput(array($notification, 'notify'), array('listeners' => 'status')) . $html,
'status' => array(),
'type' => 'text/html; charset=' . NLS::getCharset()
)
' bytes' . "\n" .
sprintf(ngettext("File Count: %d file", "File Count: %d files", $fileCount), $fileCount) .
"\n\n" .
- String::pad(_("File Name"), $maxlen, ' ', STR_PAD_RIGHT) .
- String::pad(_("Attributes"), 10, ' ', STR_PAD_LEFT) .
- String::pad(_("Size"), 10, ' ', STR_PAD_LEFT) .
- String::pad(_("Modified Date"), 19, ' ', STR_PAD_LEFT) .
- String::pad(_("Method"), 10, ' ', STR_PAD_LEFT) .
- String::pad(_("CRC"), 10, ' ', STR_PAD_LEFT) .
- String::pad(_("Ratio"), 10, ' ', STR_PAD_LEFT) .
+ Horde_String::pad(_("File Name"), $maxlen, ' ', STR_PAD_RIGHT) .
+ Horde_String::pad(_("Attributes"), 10, ' ', STR_PAD_LEFT) .
+ Horde_String::pad(_("Size"), 10, ' ', STR_PAD_LEFT) .
+ Horde_String::pad(_("Modified Date"), 19, ' ', STR_PAD_LEFT) .
+ Horde_String::pad(_("Method"), 10, ' ', STR_PAD_LEFT) .
+ Horde_String::pad(_("CRC"), 10, ' ', STR_PAD_LEFT) .
+ Horde_String::pad(_("Ratio"), 10, ' ', STR_PAD_LEFT) .
"\n"
) . str_repeat('-', 69 + $maxlen) . "\n";
? 0
: 100 * ($val['csize'] / $val['size']);
- $val['name'] = String::pad($val['name'], $maxlen, ' ', STR_PAD_RIGHT);
- $val['attr'] = String::pad($val['attr'], 10,' ', STR_PAD_LEFT);
- $val['size'] = String::pad($val['size'], 10, ' ', STR_PAD_LEFT);
- $val['date'] = String::pad(strftime("%d-%b-%Y %H:%M", $val['date']), 19, ' ', STR_PAD_LEFT);
- $val['method'] = String::pad($val['method'], 10, ' ', STR_PAD_LEFT);
- $val['crc'] = String::pad($val['crc'], 10, ' ', STR_PAD_LEFT);
- $val['ratio'] = String::pad(sprintf("%1.1f%%", $ratio), 10, ' ', STR_PAD_LEFT);
+ $val['name'] = Horde_String::pad($val['name'], $maxlen, ' ', STR_PAD_RIGHT);
+ $val['attr'] = Horde_String::pad($val['attr'], 10,' ', STR_PAD_LEFT);
+ $val['size'] = Horde_String::pad($val['size'], 10, ' ', STR_PAD_LEFT);
+ $val['date'] = Horde_String::pad(strftime("%d-%b-%Y %H:%M", $val['date']), 19, ' ', STR_PAD_LEFT);
+ $val['method'] = Horde_String::pad($val['method'], 10, ' ', STR_PAD_LEFT);
+ $val['crc'] = Horde_String::pad($val['crc'], 10, ' ', STR_PAD_LEFT);
+ $val['ratio'] = Horde_String::pad(sprintf("%1.1f%%", $ratio), 10, ' ', STR_PAD_LEFT);
$val = array_map(array('Text', 'htmlAllSpaces'), $val);
if (!is_null($this->_callback)) {
return $handler->getResponse($request);
}
- /* We can't use Util::bufferOutput() here for some reason. */
+ /* We can't use Horde_Util::bufferOutput() here for some reason. */
$beginTime = time();
ob_start();
$this->_server->handle($request);
}
$properties[$prop['xmlns']][$prop['name']] = $prop['name'];
}
-
+
// Handle certain standard properties specially
if (in_array('displayname', $properties['DAV:'])) {
- $props[] = $this->mkprop('displayname', String::convertCharset($item['name'], NLS::getCharset(), 'UTF-8'));
+ $props[] = $this->mkprop('displayname', Horde_String::convertCharset($item['name'], NLS::getCharset(), 'UTF-8'));
unset($properties['DAV:']['displayname']);
}
if (in_array('getlastmodified', $properties['DAV:'])) {
{
$ret = false;
- require_once 'Horde/Util.php';
- if (Util::extensionExists('mcrypt')) {
+ if (Horde_Util::extensionExists('mcrypt')) {
$old_error = error_reporting(0);
$td = mcrypt_module_open(MCRYPT_GOST, '', MCRYPT_MODE_ECB, '');
if ($td) {
{
switch ($mode) {
case self::BZIP:
- return Util::extensionExists('bz2');
+ return Horde_Util::extensionExists('bz2');
case self::WDDX:
- return Util::extensionExists('wddx');
+ return Horde_Util::extensionExists('wddx');
case self::IMAPUTF7:
return class_exists('Horde_Imap_Client');
case self::GZ_DEFLATE:
case self::GZ_COMPRESS:
case self::GZ_ENCODE:
- return Util::extensionExists('zlib');
+ return Horde_Util::extensionExists('zlib');
case self::SQLXML:
return @include_once 'XML/sql2xml.php';
case self::LZF:
- return Util::extensionExists('lzf');
+ return Horde_Util::extensionExists('lzf');
case self::NONE:
case self::BASIC:
break;
case self::IMAPUTF7:
- require_once 'Horde/String.php';
- $data = Horde_Imap_Client_Utf7imap::Utf8ToUtf7Imap(String::convertCharset($data, 'ISO-8859-1', 'UTF-8'));
+ $data = Horde_Imap_Client_Utf7imap::Utf8ToUtf7Imap(Horde_String::convertCharset($data, 'ISO-8859-1', 'UTF-8'));
break;
case self::IMAPUTF8:
// $params = Source character set
case self::UTF7:
- require_once 'Horde/String.php';
- $data = String::convertCharset($data, $params, 'UTF-7');
+ $data = Horde_String::convertCharset($data, $params, 'UTF-7');
break;
// $params = Source character set
// $params = Source character set
case self::JSON:
- require_once 'Horde/String.php';
if (!empty($params)) {
- $data = String::convertCharset($data, $params, 'UTF-8');
+ $data = Horde_String::convertCharset($data, $params, 'UTF-8');
}
$data = json_encode($data);
break;
break;
case self::IMAPUTF7:
- require_once 'Horde/String.php';
- $data = String::convertCharset(Horde_Imap_Client_Utf7imap::Utf7ImapToUtf8($data), 'UTF-8', 'ISO-8859-1');
+ $data = Horde_String::convertCharset(Horde_Imap_Client_Utf7imap::Utf7ImapToUtf8($data), 'UTF-8', 'ISO-8859-1');
break;
case self::IMAPUTF8:
// $params = Output character set
case self::UTF7:
- require_once 'Horde/String.php';
- $data = String::convertCharset($data, 'utf-7', $params);
+ $data = Horde_String::convertCharset($data, 'utf-7', $params);
break;
// $params = Output character set
$sessions = array();
$path = session_save_path();
- $d = @dir(empty($path) ? Util::getTempDir() : $path);
+ $d = @dir(empty($path) ? Horde_Util::getTempDir() : $path);
if (!$d) {
return $sessions;
}
<?php
-
-require_once 'Horde/String.php';
-
/**
* The Horde_SpellChecker:: class provides a unified spellchecker API.
*
*/
static public function getInstance($driver, $params = array())
{
- $class = 'Horde_SpellChecker_' . String::ucfirst(basename($driver));
+ $class = 'Horde_SpellChecker_' . Horde_String::ucfirst(basename($driver));
if (!class_exists($class)) {
throw new Exception('Driver ' . $driver . ' not found');
}
{
return (empty($this->_localDict))
? false
- : in_array(String::lower($word, true), $this->_localDict);
+ : in_array(Horde_String::lower($word, true), $this->_localDict);
}
}
// Write to stdin.
if ($this->_encoding) {
- $input = String::convertCharset($input, $charset, $this->_encoding);
+ $input = Horde_String::convertCharset($input, $charset, $this->_encoding);
}
// The '^' character tells aspell to spell check the entire line.
if (strlen($out) === 0) {
if ($this->_encoding) {
- $err = String::convertCharset($err, $this->_encoding, $charset);
+ $err = Horde_String::convertCharset($err, $this->_encoding, $charset);
}
throw Exception('Spellcheck failed. Command line: ', $this->_cmd());
}
if ($this->_encoding) {
- $out = String::convertCharset($out, $this->_encoding, $charset);
+ $out = Horde_String::convertCharset($out, $this->_encoding, $charset);
}
// Parse output.
if (empty($line)) {
/* Line is empty. */
$this->_output[] = array('text' => $quotestr, 'level' => $num_quotes);
- } elseif (empty($this->_maxlength) || ((String::length($line, $this->_charset) + $num_quotes) <= $this->_maxlength)) {
+ } elseif (empty($this->_maxlength) || ((Horde_String::length($line, $this->_charset) + $num_quotes) <= $this->_maxlength)) {
/* Line does not require rewrapping. */
$this->_output[] = array('text' => $quotestr . $this->_stuff($line, $num_quotes, $toflowed), 'level' => $num_quotes);
} else {
while ($line) {
/* Stuff and re-quote the line. */
$line = $quotestr . $this->_stuff($line, $num_quotes, $toflowed);
- $line_length = String::length($line, $this->_charset);
+ $line_length = Horde_String::length($line, $this->_charset);
if ($line_length <= $this->_optlength) {
/* Remaining section of line is short enough. */
$this->_output[] = array('text' => $line, 'level' => $num_quotes);
break;
- } elseif ($m = String::regexMatch($line, array('^(.{' . $min . ',' . $opt . '}) (.*)', '^(.{' . $min . ',' . $this->_maxlength . '}) (.*)', '^(.{' . $min . ',})? (.*)'), $this->_charset)) {
+ } elseif ($m = Horde_String::regexMatch($line, array('^(.{' . $min . ',' . $opt . '}) (.*)', '^(.{' . $min . ',' . $this->_maxlength . '}) (.*)', '^(.{' . $min . ',})? (.*)'), $this->_charset)) {
/* We need to wrap text at a certain number of
* *characters*, not a certain number of *bytes*;
* thus the need for a multibyte capable regex.
* absolutely sure it does not exceed 998 characters
* in length or else we must truncate. */
if ($line_length > 998) {
- $this->_output[] = array('text' => String::substr($line, 0, 998, $this->_charset), 'level' => $num_quotes);
- $line = String::substr($line, 998, null, $this->_charset);
+ $this->_output[] = array('text' => Horde_String::substr($line, 0, 998, $this->_charset), 'level' => $num_quotes);
+ $line = Horde_String::substr($line, 998, null, $this->_charset);
} else {
$this->_output[] = array('text' => $line, 'level' => $num_quotes);
break;
*/
public function generateId($seed = '')
{
- require_once 'Horde/Util.php';
- return Util::uriB64Encode(pack('H*', sha1(uniqid(mt_rand(), true) . $seed . (isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : ''))));
+ return Horde_Util::uriB64Encode(pack('H*', sha1(uniqid(mt_rand(), true) . $seed . (isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : ''))));
}
/**
/* Choose the directory to save the stub files. */
if (!isset($this->_params['token_dir'])) {
- $this->_params['token_dir'] = Util::getTempDir();
+ $this->_params['token_dir'] = Horde_Util::getTempDir();
}
/* Set timeout to 24 hours if not specified. */
return true;
}
- $result = Util::assertDriverConfig($this->_params, array('phptype'),
- 'token SQL', array('driver' => 'token'));
+ $result = Horde_Util::assertDriverConfig($this->_params, array('phptype'), 'token SQL', array('driver' => 'token'));
if (is_a($result, 'PEAR_Error')) {
return $result;
}
--- /dev/null
+<?php
+/**
+ * The Horde_Array:: class provides various methods for array manipulation.
+ *
+ * Copyright 2003-2009 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * @author Michael Slusarz <slusarz@horde.org>
+ * @author Marko Djukic <marko@oblo.com>
+ * @author Jan Schneider <jan@horde.org>
+ * @package Horde_Util
+ */
+class Horde_Array
+{
+ /**
+ * Prepare a list of addresses for storage.
+ * Namely, trims and lowercases all addresses and then sort.
+ *
+ * @param array $addr The list of addresses.
+ *
+ * @return array The list of addresses, prepared for storage.
+ */
+ static public function prepareAddressList($addr)
+ {
+ /* Remove any extra space in the address and make it lowercase. */
+ $addr = array_map(array('String', 'lower'), array_map('trim', $addr));
+
+ /* Remove duplicate entries. */
+ $addr = array_keys(array_flip($addr));
+
+ /* Sort the list. */
+ usort($addr, array('Horde_Array', 'sortAddressList'));
+
+ return $addr;
+ }
+
+ /**
+ * Function used by usort() to sort an address list.
+ * e.g. usort($foo, array('Horde_Array', 'sortAddressList'));
+ *
+ * @param string $a Address #1.
+ * @param string $b Address #2.
+ *
+ * @return integer -1, 0, or 1.
+ */
+ static public function sortAddressList($a, $b)
+ {
+ $a = explode('@', $a);
+ $b = explode('@', $b);
+
+ /* One of the addresses doesn't have a host name. */
+ if (empty($a[0])) {
+ array_shift($a);
+ }
+ if (empty($b[0])) {
+ array_shift($b);
+ }
+ if (count($a) != count($b)) {
+ return (count($a) > count($b));
+ }
+
+ /* The addresses have different hostname or not hostname and
+ * different mailbox names. */
+ if ($a[(count($a) - 1)] != $b[(count($b) - 1)]) {
+ return strcmp($a[(count($a) - 1)], $b[(count($b) - 1)]);
+ }
+
+ /* Compare mailbox names. */
+ return strcmp($a[0], $b[0]);
+ }
+
+ /**
+ * Sorts an array on a specified key. If the key does not exist,
+ * defaults to the first key of the array.
+ *
+ * @param array &$array The array to be sorted, passed by reference.
+ * @param string $key The key by which to sort. If not specified then
+ * the first key is used.
+ * @param integer $dir Sort direction:
+ * 0 = ascending (default)
+ * 1 = descending
+ * @param boolean $assoc Keep key value association?
+ */
+ static public function arraySort(&$array, $key = null, $dir = 0,
+ $assoc = true)
+ {
+ /* Return if the array is empty. */
+ if (empty($array)) {
+ return;
+ }
+
+ /* If no key to sort by is specified, use the first key of the
+ * first element. */
+ if (is_null($key)) {
+ reset($array);
+ $key = array_shift(array_keys(current($array)));
+ }
+
+ /* Call the appropriate sort function. */
+ $helper = new Horde_Array_Sort_Helper();
+ $helper->key = $key;
+ $function = $dir ? 'reverseCompare' : 'compare';
+ if ($assoc) {
+ uasort($array, array($helper, $function));
+ } else {
+ usort($array, array($helper, $function));
+ }
+ }
+
+ /**
+ * Given an HTML type array field "example[key1][key2][key3]" breaks up
+ * the keys so that they could be used to reference a regular PHP array.
+ *
+ * @param string $field The field name to be examined.
+ * @param string &$base Set to the base element.
+ * @param array &$keys Set to the list of keys.
+ *
+ * @return boolean True on sucess, false on error.
+ */
+ static public function getArrayParts($field, &$base, &$keys)
+ {
+ if (!preg_match('|([^\[]*)((\[[^\[\]]*\])+)|', $field, $matches)) {
+ return false;
+ }
+
+ $base = $matches[1];
+ $keys = explode('][', $matches[2]);
+ $keys[0] = substr($keys[0], 1);
+ $keys[count($keys) - 1] = substr($keys[count($keys) - 1], 0, strlen($keys[count($keys) - 1]) - 1);
+ return true;
+ }
+
+ /**
+ * Using an array of keys iterate through the array following the
+ * keys to find the final key value. If a value is passed then set
+ * that value.
+ *
+ * @param array &$array The array to be used.
+ * @param array &$keys The key path to follow as an array.
+ * @param array $value If set the target element will have this value set
+ * to it.
+ *
+ * @return mixed The final value of the key path.
+ */
+ static public function getElement(&$array, &$keys, $value = null)
+ {
+ if (count($keys)) {
+ $key = array_shift($keys);
+ return isset($array[$key])
+ ? self::getElement($array[$key], $keys, $value)
+ : false;
+ }
+
+ if (!is_null($value)) {
+ $array = $value;
+ }
+
+ return $array;
+ }
+
+ /**
+ * Returns a rectangle of a two-dimensional array.
+ *
+ * @param array $array The array to extract the rectangle from.
+ * @param integer $row The start row of the rectangle.
+ * @param integer $col The start column of the rectangle.
+ * @param integer $height The height of the rectangle.
+ * @param integer $width The width of the rectangle.
+ *
+ * @return array The extracted rectangle.
+ */
+ static public function getRectangle($array, $row, $col, $height, $width)
+ {
+ $rec = array();
+ for ($y = $row; $y < $row + $height; $y++) {
+ $rec[] = array_slice($array[$y], $col, $width);
+ }
+ return $rec;
+ }
+
+ /**
+ * Given an array, returns an associative array with each element key
+ * derived from its value.
+ * For example:
+ * array(0 => 'foo', 1 => 'bar')
+ * would become:
+ * array('foo' => 'foo', 'bar' => 'bar')
+ *
+ * @param array $array An array of values.
+ *
+ * @return array An array with keys the same as values.
+ */
+ static public function valuesToKeys($array)
+ {
+ if (!$array) {
+ return array();
+ }
+
+ $values = array_values($array);
+ return array_combine($values, $values);
+ }
+
+ /**
+ * Enhanced array_merge_recursive() function. Main difference from PHP's
+ * stock function is later value always overwrites earlier value (stock
+ * function will instead create an array with all values of key).
+ *
+ * @param array $a1 The old array.
+ * @param array $a2 The new array.
+ *
+ * @return array The merged array.
+ */
+ static public function array_merge_recursive_overwrite($a1, $a2)
+ {
+ foreach ($a2 as $key => $val) {
+ if (!isset($a1[$key])) {
+ $a1[$key] = array();
+ }
+
+ $a1[$key] = (is_array($val))
+ ? self::array_merge_recursive_overwrite($a1[$key], $val)
+ : $val;
+ }
+
+ return $a1;
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * Helper class for sorting arrays on arbitrary criteria for usort/uasort.
+ *
+ * Copyright 2003-2009 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * @author Michael Slusarz <slusarz@horde.org>
+ * @author Marko Djukic <marko@oblo.com>
+ * @author Jan Schneider <jan@horde.org>
+ * @package Horde_Util
+ */
+class Horde_Array_Sort_Helper
+{
+ /**
+ * The array key to sort by.
+ *
+ * @var string
+ */
+ public $key;
+
+ /**
+ * Compare two associative arrays by the array key defined in self::$key.
+ *
+ * @param array $a
+ * @param array $b
+ */
+ public function compare($a, $b)
+ {
+ return strcoll(Horde_String::lower($a[$this->key], true), Horde_String::lower($b[$this->key], true));
+ }
+
+ /**
+ * Compare, in reverse order, two associative arrays by the array key
+ * defined in self::$key.
+ *
+ * @param scalar $a TODO
+ * @param scalar $b TODO
+ *
+ * @return TODO
+ */
+ public function reverseCompare($a, $b)
+ {
+ return strcoll(Horde_String::lower($b[$this->key], true), Horde_String::lower($a[$this->key], true));
+ }
+
+ /**
+ * Compare array keys case insensitively for uksort.
+ *
+ * @param scalar $a TODO
+ * @param scalar $b TODO
+ *
+ * @return TODO
+ */
+ public function compareKeys($a, $b)
+ {
+ return strcoll(Horde_String::lower($a, true), Horde_String::lower($b, true));
+ }
+
+ /**
+ * Compare, in reverse order, array keys case insensitively for uksort.
+ *
+ * @param scalar $a TODO
+ * @param scalar $b TODO
+ *
+ * @return TODO
+ */
+ public function reverseCompareKeys($a, $b)
+ {
+ return strcoll(Horde_String::lower($b, true), Horde_String::lower($a, true));
+ }
+}
--- /dev/null
+<?php
+/**
+ * The Horde_String:: class provides static methods for charset and locale
+ * safe string manipulation.
+ *
+ * Copyright 2003-2009 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * @author Jan Schneider <jan@horde.org>
+ * @package Horde_Util
+ */
+class Horde_String
+{
+ /**
+ * Default charset.
+ *
+ * @var string
+ */
+ static protected $_charset = 'iso-8859-1';
+
+ /**
+ * lower() cache.
+ *
+ * @var array
+ */
+ static protected $_lowers = array();
+
+ /**
+ * upper() cache.
+ *
+ * @var array
+ */
+ static protected $_uppers = array();
+
+ /**
+ * Sets a default charset that the methods will use if none is explicitly
+ * specified.
+ *
+ * @param string $charset The charset to use as the default one.
+ */
+ static public function setDefaultCharset($charset)
+ {
+ self::$_charset = $charset;
+ if (Horde_Util::extensionExists('mbstring')) {
+ $old_error = error_reporting(0);
+ mb_regex_encoding(self::_mbstringCharset($charset));
+ error_reporting($old_error);
+ }
+ }
+
+ /**
+ * Converts a string from one charset to another.
+ *
+ * Works only if either the iconv or the mbstring extension
+ * are present and best if both are available.
+ * The original string is returned if conversion failed or none
+ * of the extensions were available.
+ *
+ * @param mixed $input The data to be converted. If $input is an an array,
+ * the array's values get converted recursively.
+ * @param string $from The string's current charset.
+ * @param string $to The charset to convert the string to. If not
+ * specified, the global variable $_charset will
+ * be used.
+ *
+ * @return mixed The converted input data.
+ */
+ static public function convertCharset($input, $from, $to = null)
+ {
+ /* Don't bother converting numbers. */
+ if (is_numeric($input)) {
+ return $input;
+ }
+
+ /* Get the user's default character set if none passed in. */
+ if (is_null($to)) {
+ $to = self::$_charset;
+ }
+
+ /* If the from and to character sets are identical, return now. */
+ $from = self::lower($from);
+ $to = self::lower($to);
+ if ($from == $to) {
+ return $input;
+ }
+
+ if (is_array($input)) {
+ $tmp = array();
+ reset($input);
+ while (list($key, $val) = each($input)) {
+ $tmp[self::_convertCharset($key, $from, $to)] = self::convertCharset($val, $from, $to);
+ }
+ return $tmp;
+ }
+
+ if (is_object($input)) {
+ // PEAR_Error objects are almost guaranteed to contain recursion,
+ // which will cause a segfault in PHP. We should never reach
+ // this line, but add a check and a log message to help the devs
+ // track down and fix this issue.
+ if (is_a($input, 'PEAR_Error')) {
+ Horde::logMessage('Called convertCharset() on a PEAR_Error object. ' . print_r($input, true), __FILE__, __LINE__, PEAR_LOG_DEBUG);
+ return '';
+ }
+ $vars = get_object_vars($input);
+ while (list($key, $val) = each($vars)) {
+ $input->$key = self::convertCharset($val, $from, $to);
+ }
+ return $input;
+ }
+
+ if (!is_string($input)) {
+ return $input;
+ }
+
+ return self::_convertCharset($input, $from, $to);
+ }
+
+ /**
+ * Internal function used to do charset conversion.
+ *
+ * @param string $input See self::convertCharset().
+ * @param string $from See self::convertCharset().
+ * @param string $to See self::convertCharset().
+ *
+ * @return string The converted string.
+ */
+ static protected function _convertCharset($input, $from, $to)
+ {
+ /* Use utf8_[en|de]code() if possible and if the string isn't too
+ * large (less than 16 MB = 16 * 1024 * 1024 = 16777216 bytes) - these
+ * functions use more memory. */
+ if ((strlen($input) < 16777216) ||
+ !(Horde_Util::extensionExists('iconv') || Horde_Util::extensionExists('mbstring'))) {
+ if (($to == 'utf-8') &&
+ in_array($from, array('iso-8859-1', 'us-ascii'))) {
+ return utf8_encode($input);
+ }
+
+ if (($from == 'utf-8') &&
+ in_array($to, array('iso-8859-1', 'us-ascii'))) {
+ return utf8_decode($input);
+ }
+ }
+
+ /* Try UTF7-IMAP conversions. */
+ if (($from == 'utf7-imap') || ($to == 'utf7-imap')) {
+ try {
+ if ($from == 'utf7-imap') {
+ return self::convertCharset(Horde_Imap_Client_Utf7imap::Utf7ImapToUtf8($input), 'UTF-8', $to);
+ } else {
+ if ($from == 'utf-8') {
+ $conv = $input;
+ } else {
+ $conv = self::convertCharset($input, $from, 'UTF-8');
+ }
+ return Horde_Imap_Client_Utf7imap::Utf8ToUtf7Imap($conv);
+ }
+ } catch (Horde_Imap_Client_Exception $e) {
+ return $input;
+ }
+ }
+
+ /* Try iconv with transliteration. */
+ if (Horde_Util::extensionExists('iconv')) {
+ /* We need to tack an extra character temporarily because of a bug
+ * in iconv() if the last character is not a 7 bit ASCII
+ * character. */
+ $oldTrackErrors = ini_set('track_errors', 1);
+ unset($php_errormsg);
+ $out = @iconv($from, $to . '//TRANSLIT', $input . 'x');
+ $errmsg = isset($php_errormsg);
+ ini_set('track_errors', $oldTrackErrors);
+ if (!$errmsg) {
+ return self::substr($out, 0, -1, $to);
+ }
+ }
+
+ /* Try mbstring. */
+ if (Horde_Util::extensionExists('mbstring')) {
+ $old_error = error_reporting(0);
+ $out = mb_convert_encoding($input, $to, self::_mbstringCharset($from));
+ error_reporting($old_error);
+ if (!empty($out)) {
+ return $out;
+ }
+ }
+
+ return $input;
+ }
+
+ /**
+ * Makes a string lowercase.
+ *
+ * @param string $string The string to be converted.
+ * @param boolean $locale If true the string will be converted based on
+ * a given charset, locale independent else.
+ * @param string $charset If $locale is true, the charset to use when
+ * converting. If not provided the current
+ * charset.
+ *
+ * @return string The string with lowercase characters.
+ */
+ static public function lower($string, $locale = false, $charset = null)
+ {
+ if ($locale) {
+ if (Horde_Util::extensionExists('mbstring')) {
+ if (is_null($charset)) {
+ $charset = self::$_charset;
+ }
+ $old_error = error_reporting(0);
+ $ret = mb_strtolower($string, self::_mbstringCharset($charset));
+ error_reporting($old_error);
+ if (!empty($ret)) {
+ return $ret;
+ }
+ }
+ return strtolower($string);
+ }
+
+ if (!isset(self::$_lowers[$string])) {
+ $language = setlocale(LC_CTYPE, 0);
+ setlocale(LC_CTYPE, 'C');
+ self::$_lowers[$string] = strtolower($string);
+ setlocale(LC_CTYPE, $language);
+ }
+
+ return self::$_lowers[$string];
+ }
+
+ /**
+ * Makes a string uppercase.
+ *
+ * @param string $string The string to be converted.
+ * @param boolean $locale If true the string will be converted based on a
+ * given charset, locale independent else.
+ * @param string $charset If $locale is true, the charset to use when
+ * converting. If not provided the current charset.
+ *
+ * @return string The string with uppercase characters.
+ */
+ static public function upper($string, $locale = false, $charset = null)
+ {
+ if ($locale) {
+ if (Horde_Util::extensionExists('mbstring')) {
+ if (is_null($charset)) {
+ $charset = self::$_charset;
+ }
+ $old_error = error_reporting(0);
+ $ret = mb_strtoupper($string, self::_mbstringCharset($charset));
+ error_reporting($old_error);
+ if (!empty($ret)) {
+ return $ret;
+ }
+ }
+ return strtoupper($string);
+ }
+
+ if (!isset(self::$_uppers[$string])) {
+ $language = setlocale(LC_CTYPE, 0);
+ setlocale(LC_CTYPE, 'C');
+ self::$_uppers[$string] = strtoupper($string);
+ setlocale(LC_CTYPE, $language);
+ }
+
+ return self::$_uppers[$string];
+ }
+
+ /**
+ * Returns a string with the first letter capitalized if it is
+ * alphabetic.
+ *
+ * @param string $string The string to be capitalized.
+ * @param boolean $locale If true the string will be converted based on a
+ * given charset, locale independent else.
+ * @param string $charset The charset to use, defaults to current charset.
+ *
+ * @return string The capitalized string.
+ */
+ static public function ucfirst($string, $locale = false, $charset = null)
+ {
+ if ($locale) {
+ $first = self::substr($string, 0, 1, $charset);
+ if (self::isAlpha($first, $charset)) {
+ $string = self::upper($first, true, $charset) . self::substr($string, 1, null, $charset);
+ }
+ } else {
+ $string = self::upper(substr($string, 0, 1), false) . substr($string, 1);
+ }
+
+ return $string;
+ }
+
+ /**
+ * Returns part of a string.
+ *
+ * @param string $string The string to be converted.
+ * @param integer $start The part's start position, zero based.
+ * @param integer $length The part's length.
+ * @param string $charset The charset to use when calculating the part's
+ * position and length, defaults to current
+ * charset.
+ *
+ * @return string The string's part.
+ */
+ static public function substr($string, $start, $length = null,
+ $charset = null)
+ {
+ if (is_null($length)) {
+ $length = self::length($string, $charset) - $start;
+ }
+
+ if ($length == 0) {
+ return '';
+ }
+
+ /* Try iconv. */
+ if (Horde_Util::extensionExists('iconv')) {
+ if (is_null($charset)) {
+ $charset = self::$_charset;
+ }
+
+ $old_error = error_reporting(0);
+ $ret = iconv_substr($string, $start, $length, $charset);
+ error_reporting($old_error);
+
+ /* iconv_substr() returns false on failure. */
+ if ($ret !== false) {
+ return $ret;
+ }
+ }
+
+ /* Try mbstring. */
+ if (Horde_Util::extensionExists('mbstring')) {
+ if (is_null($charset)) {
+ $charset = self::$_charset;
+ }
+ $old_error = error_reporting(0);
+ $ret = mb_substr($string, $start, $length, self::_mbstringCharset($charset));
+ error_reporting($old_error);
+
+ /* mb_substr() returns empty string on failure. */
+ if (strlen($ret)) {
+ return $ret;
+ }
+ }
+
+ return substr($string, $start, $length);
+ }
+
+ /**
+ * Returns the character (not byte) length of a string.
+ *
+ * @param string $string The string to return the length of.
+ * @param string $charset The charset to use when calculating the string's
+ * length.
+ *
+ * @return integer The string's length.
+ */
+ static public function length($string, $charset = null)
+ {
+ if (is_null($charset)) {
+ $charset = self::$_charset;
+ }
+ $charset = self::lower($charset);
+
+ if ($charset == 'utf-8' || $charset == 'utf8') {
+ return strlen(utf8_decode($string));
+ }
+
+ if (Horde_Util::extensionExists('mbstring')) {
+ $old_error = error_reporting(0);
+ $ret = mb_strlen($string, self::_mbstringCharset($charset));
+ error_reporting($old_error);
+ if (!empty($ret)) {
+ return $ret;
+ }
+ }
+
+ return strlen($string);
+ }
+
+ /**
+ * Returns the numeric position of the first occurrence of $needle
+ * in the $haystack string.
+ *
+ * @param string $haystack The string to search through.
+ * @param string $needle The string to search for.
+ * @param integer $offset Allows to specify which character in haystack
+ * to start searching.
+ * @param string $charset The charset to use when searching for the
+ * $needle string.
+ *
+ * @return integer The position of first occurrence.
+ */
+ static public function pos($haystack, $needle, $offset = 0,
+ $charset = null)
+ {
+ if (Horde_Util::extensionExists('mbstring')) {
+ if (is_null($charset)) {
+ $charset = self::$_charset;
+ }
+ $track_errors = ini_set('track_errors', 1);
+ $old_error = error_reporting(0);
+ $ret = mb_strpos($haystack, $needle, $offset, self::_mbstringCharset($charset));
+ error_reporting($old_error);
+ ini_set('track_errors', $track_errors);
+ if (!isset($php_errormsg)) {
+ return $ret;
+ }
+ }
+
+ return strpos($haystack, $needle, $offset);
+ }
+
+ /**
+ * Returns a string padded to a certain length with another string.
+ * This method behaves exactly like str_pad() but is multibyte safe.
+ *
+ * @param string $input The string to be padded.
+ * @param integer $length The length of the resulting string.
+ * @param string $pad The string to pad the input string with. Must
+ * be in the same charset like the input string.
+ * @param const $type The padding type. One of STR_PAD_LEFT,
+ * STR_PAD_RIGHT, or STR_PAD_BOTH.
+ * @param string $charset The charset of the input and the padding
+ * strings.
+ *
+ * @return string The padded string.
+ */
+ static public function pad($input, $length, $pad = ' ',
+ $type = STR_PAD_RIGHT, $charset = null)
+ {
+ $mb_length = self::length($input, $charset);
+ $sb_length = strlen($input);
+ $pad_length = self::length($pad, $charset);
+
+ /* Return if we already have the length. */
+ if ($mb_length >= $length) {
+ return $input;
+ }
+
+ /* Shortcut for single byte strings. */
+ if ($mb_length == $sb_length && $pad_length == strlen($pad)) {
+ return str_pad($input, $length, $pad, $type);
+ }
+
+ switch ($type) {
+ case STR_PAD_LEFT:
+ $left = $length - $mb_length;
+ $output = self::substr(str_repeat($pad, ceil($left / $pad_length)), 0, $left, $charset) . $input;
+ break;
+
+ case STR_PAD_BOTH:
+ $left = floor(($length - $mb_length) / 2);
+ $right = ceil(($length - $mb_length) / 2);
+ $output = self::substr(str_repeat($pad, ceil($left / $pad_length)), 0, $left, $charset) .
+ $input .
+ self::substr(str_repeat($pad, ceil($right / $pad_length)), 0, $right, $charset);
+ break;
+
+ case STR_PAD_RIGHT:
+ $right = $length - $mb_length;
+ $output = $input . self::substr(str_repeat($pad, ceil($right / $pad_length)), 0, $right, $charset);
+ break;
+ }
+
+ return $output;
+ }
+
+ /**
+ * Wraps the text of a message.
+ *
+ * @param string $string String containing the text to wrap.
+ * @param integer $width Wrap the string at this number of
+ * characters.
+ * @param string $break Character(s) to use when breaking lines.
+ * @param boolean $cut Whether to cut inside words if a line
+ * can't be wrapped.
+ * @param string $charset Character set to use when breaking lines.
+ * @param boolean $line_folding Whether to apply line folding rules per
+ * RFC 822 or similar. The correct break
+ * characters including leading whitespace
+ * have to be specified too.
+ *
+ * @return string String containing the wrapped text.
+ */
+ static public function wordwrap($string, $width = 75, $break = "\n",
+ $cut = false, $charset = null,
+ $line_folding = false)
+ {
+ /* Get the user's default character set if none passed in. */
+ if (is_null($charset)) {
+ $charset = self::$_charset;
+ }
+
+ $charset = self::_mbstringCharset($charset);
+ $string = self::convertCharset($string, $charset, 'utf-8');
+ $wrapped = '';
+
+ while (self::length($string, 'utf-8') > $width) {
+ $line = self::substr($string, 0, $width, 'utf-8');
+ $string = self::substr($string, self::length($line, 'utf-8'), null, 'utf-8');
+
+ // Make sure didn't cut a word, unless we want hard breaks anyway.
+ if (!$cut && preg_match('/^(.+?)(\s|\r?\n)/u', $string, $match)) {
+ $line .= $match[1];
+ $string = self::substr($string, self::length($match[1], 'utf-8'), null, 'utf-8');
+ }
+
+ // Wrap at existing line breaks.
+ if (preg_match('/^(.*?)(\r?\n)(.*)$/u', $line, $match)) {
+ $wrapped .= $match[1] . $match[2];
+ $string = $match[3] . $string;
+ continue;
+ }
+
+ // Wrap at the last colon or semicolon followed by a whitespace if
+ // doing line folding.
+ if ($line_folding &&
+ preg_match('/^(.*?)(;|:)(\s+.*)$/u', $line, $match)) {
+ $wrapped .= $match[1] . $match[2] . $break;
+ $string = $match[3] . $string;
+ continue;
+ }
+
+ // Wrap at the last whitespace of $line.
+ $sub = $line_folding
+ ? '(.+[^\s])'
+ : '(.*)';
+
+ if (preg_match('/^' . $sub . '(\s+)(.*)$/u', $line, $match)) {
+ $wrapped .= $match[1] . $break;
+ $string = ($line_folding ? $match[2] : '') . $match[3] . $string;
+ continue;
+ }
+
+ // Hard wrap if necessary.
+ if ($cut) {
+ $wrapped .= self::substr($line, 0, $width, 'utf-8') . $break;
+ $string = self::substr($line, $width, null, 'utf-8') . $string;
+ continue;
+ }
+
+ $wrapped .= $line;
+ }
+
+ return self::convertCharset($wrapped . $string, 'utf-8', $charset);
+ }
+
+ /**
+ * Wraps the text of a message.
+ *
+ * @param string $text String containing the text to wrap.
+ * @param integer $length Wrap $text at this number of characters.
+ * @param string $break_char Character(s) to use when breaking lines.
+ * @param string $charset Character set to use when breaking lines.
+ * @param boolean $quote Ignore lines that are wrapped with the '>'
+ * character (RFC 2646)? If true, we don't
+ * remove any padding whitespace at the end of
+ * the string.
+ *
+ * @return string String containing the wrapped text.
+ */
+ static public function wrap($text, $length = 80, $break_char = "\n",
+ $charset = null, $quote = false)
+ {
+ $paragraphs = array();
+
+ foreach (preg_split('/\r?\n/', $text) as $input) {
+ if ($quote && (strpos($input, '>') === 0)) {
+ $line = $input;
+ } else {
+ /* We need to handle the Usenet-style signature line
+ * separately; since the space after the two dashes is
+ * REQUIRED, we don't want to trim the line. */
+ if ($input != '-- ') {
+ $input = rtrim($input);
+ }
+ $line = self::wordwrap($input, $length, $break_char, false, $charset);
+ }
+
+ $paragraphs[] = $line;
+ }
+
+ return implode($break_char, $paragraphs);
+ }
+
+ /**
+ * Returns true if the every character in the parameter is an alphabetic
+ * character.
+ *
+ * @param string $string The string to test.
+ * @param string $charset The charset to use when testing the string.
+ *
+ * @return boolean True if the parameter was alphabetic only.
+ */
+ static public function isAlpha($string, $charset = null)
+ {
+ if (!Horde_Util::extensionExists('mbstring')) {
+ return ctype_alpha($string);
+ }
+
+ $charset = self::_mbstringCharset($charset);
+ $old_charset = mb_regex_encoding();
+ $old_error = error_reporting(0);
+
+ if ($charset != $old_charset) {
+ mb_regex_encoding($charset);
+ }
+ $alpha = !mb_ereg_match('[^[:alpha:]]', $string);
+ if ($charset != $old_charset) {
+ mb_regex_encoding($old_charset);
+ }
+
+ error_reporting($old_error);
+
+ return $alpha;
+ }
+
+ /**
+ * Returns true if ever character in the parameter is a lowercase letter in
+ * the current locale.
+ *
+ * @param string $string The string to test.
+ * @param string $charset The charset to use when testing the string.
+ *
+ * @return boolean True if the parameter was lowercase.
+ */
+ static public function isLower($string, $charset = null)
+ {
+ return ((self::lower($string, true, $charset) === $string) &&
+ self::isAlpha($string, $charset));
+ }
+
+ /**
+ * Returns true if every character in the parameter is an uppercase letter
+ * in the current locale.
+ *
+ * @param string $string The string to test.
+ * @param string $charset The charset to use when testing the string.
+ *
+ * @return boolean True if the parameter was uppercase.
+ */
+ static public function isUpper($string, $charset = null)
+ {
+ return ((self::upper($string, true, $charset) === $string) &&
+ self::isAlpha($string, $charset));
+ }
+
+ /**
+ * Performs a multibyte safe regex match search on the text provided.
+ *
+ * @param string $text The text to search.
+ * @param array $regex The regular expressions to use, without perl
+ * regex delimiters (e.g. '/' or '|').
+ * @param string $charset The character set of the text.
+ *
+ * @return array The matches array from the first regex that matches.
+ */
+ static public function regexMatch($text, $regex, $charset = null)
+ {
+ if (!empty($charset)) {
+ $regex = self::convertCharset($regex, $charset, 'utf-8');
+ $text = self::convertCharset($text, $charset, 'utf-8');
+ }
+
+ $matches = array();
+ foreach ($regex as $val) {
+ if (preg_match('/' . $val . '/u', $text, $matches)) {
+ break;
+ }
+ }
+
+ if (!empty($charset)) {
+ $matches = self::convertCharset($matches, 'utf-8', $charset);
+ }
+
+ return $matches;
+ }
+
+ /**
+ * Workaround charsets that don't work with mbstring functions.
+ *
+ * @param string $charset The original charset.
+ *
+ * @return string The charset to use with mbstring functions.
+ */
+ static protected function _mbstringCharset($charset)
+ {
+ /* mbstring functions do not handle the 'ks_c_5601-1987' &
+ * 'ks_c_5601-1989' charsets. However, these charsets are used, for
+ * example, by various versions of Outlook to send Korean characters.
+ * Use UHC (CP949) encoding instead. See, e.g.,
+ * http://lists.w3.org/Archives/Public/ietf-charsets/2001AprJun/0030.html */
+ if (in_array(self::lower($charset), array('ks_c_5601-1987', 'ks_c_5601-1989'))) {
+ $charset = 'UHC';
+ }
+
+ return $charset;
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * The Horde_Util:: class provides generally useful methods.
+ *
+ * Copyright 1999-2009 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * @author Chuck Hagenbuch <chuck@horde.org>
+ * @author Jon Parise <jon@horde.org>
+ * @package Horde_Util
+ */
+class Horde_Util
+{
+ /* Error code for a missing driver configuration. */
+ const HORDE_ERROR_DRIVER_CONFIG_MISSING = 1;
+
+ /* Error code for an incomplete driver configuration. */
+ const HORDE_ERROR_DRIVER_CONFIG = 2;
+
+ /**
+ * A list of random patterns to use for overwriting purposes.
+ * See http://www.cs.auckland.ac.nz/~pgut001/pubs/secure_del.html.
+ * We save the random overwrites for efficiency reasons.
+ *
+ * @var array
+ */
+ static public $patterns = array(
+ "\x55", "\xaa", "\x92\x49\x24", "\x49\x24\x92", "\x24\x92\x49",
+ "\x00", "\x11", "\x22", "\x33", "\x44", "\x55", "\x66", "\x77",
+ "\x88", "\x99", "\xaa", "\xbb", "\xcc", "\xdd", "\xee", "\xff",
+ "\x92\x49\x24", "\x49\x24\x92", "\x24\x92\x49", "\x6d\xb6\xdb",
+ "\xb6\xdb\x6d", "\xdb\x6d\xb6"
+ );
+
+ /**
+ * TODO
+ *
+ * @var array
+ */
+ static public $dateSymbols = array(
+ 'a', 'A', 'd', 'D', 'F', 'g', 'G', 'h', 'H', 'i', 'j', 'l', 'm', 'M',
+ 'n', 'r', 's', 'T', 'w', 'W', 'y', 'Y', 'z', 'm/d/Y', 'M', "\n",
+ 'g:i a', 'G:i', "\t", 'H:i:s', '%'
+ );
+
+ /**
+ * TODO
+ *
+ * @var array
+ */
+ static public $strftimeSymbols = array(
+ '%p', '%p', '%d', '%a', '%B', '%I', '%H', '%I', '%H', '%M', '%e',
+ '%A', '%m', '%b', '%m', '%a, %e %b %Y %T %Z', '%S', '%Z', '%w', '%V',
+ '%y', '%Y', '%j', '%D', '%h', '%n', '%r', '%R', '%t', '%T', '%%'
+ );
+
+ /**
+ * Random number for nocacheUrl().
+ *
+ * @var integer.
+ */
+ static protected $_randnum = null;
+
+ /**
+ * TODO
+ */
+ static protected $_magicquotes = null;
+
+ /**
+ * TODO
+ */
+ static protected $_shutdowndata = array(
+ 'dirs' => array(),
+ 'files' => array(),
+ 'secure' => array()
+ );
+
+ /**
+ * TODO
+ */
+ static protected $_shutdownreg = false;
+
+ /**
+ * Cache for extensionExists().
+ *
+ * @var array
+ */
+ static protected $_cache = array();
+
+ /**
+ * Returns an object's clone.
+ *
+ * @param object &$obj The object to clone.
+ *
+ * @return object The cloned object.
+ */
+ static public function &cloneObject(&$obj)
+ {
+ if (!is_object($obj)) {
+ $bt = debug_backtrace();
+ if (isset($bt[1])) {
+ $caller = $bt[1]['function'];
+ if (isset($bt[1]['class'])) {
+ $caller = $bt[1]['class'].$bt[1]['type'].$caller;
+ }
+ } else {
+ $caller = 'main';
+ }
+
+ $caller .= ' on line ' . $bt[0]['line'] . ' of ' . $bt[0]['file'];
+ Horde::logMessage('Horde_Util::cloneObject called on variable of type ' . gettype($obj) . ' by ' . $caller, __FILE__, __LINE__, PEAR_LOG_DEBUG);
+
+ $ret = $obj;
+ return $ret;
+ }
+
+ $ret = clone($obj);
+ return $ret;
+ }
+
+ /**
+ * Buffers the output from a function call, like readfile() or
+ * highlight_string(), that prints the output directly, so that instead it
+ * can be returned as a string and used.
+ *
+ * @param string $function The function to run.
+ * @param mixed $arg1 First argument to $function().
+ * @param mixed $arg2 Second argument to $function().
+ * @param mixed $arg... ...
+ * @param mixed $argN Nth argument to $function().
+ *
+ * @return string The output of the function.
+ */
+ static public function bufferOutput()
+ {
+ if (func_num_args() == 0) {
+ return false;
+ }
+
+ $include = false;
+ $args = func_get_args();
+ $function = array_shift($args);
+
+ if (is_array($function)) {
+ if (!is_callable($function)) {
+ return false;
+ }
+ } elseif (($function == 'include') ||
+ ($function == 'include_once') ||
+ ($function == 'require') ||
+ ($function == 'require_once')) {
+ $include = true;
+ } elseif (!function_exists($function)) {
+ return false;
+ }
+
+ ob_start();
+ if ($include) {
+ $file = implode(',', $args);
+ switch ($function) {
+ case 'include':
+ include $file;
+ break;
+
+ case 'include_once':
+ include_once $file;
+ break;
+
+ case 'require':
+ require $file;
+ break;
+
+ case 'require_once':
+ require_once $file;
+ break;
+ }
+ } else {
+ call_user_func_array($function, $args);
+ }
+
+ return ob_get_clean();
+ }
+
+ /**
+ * Checks to see if a value has been set by the script and not by GET,
+ * POST, or cookie input. The value being checked MUST be in the global
+ * scope.
+ *
+ * @param string $varname The variable name to check.
+ * @param mixed $default Default value if the variable isn't present
+ * or was specified by the user. Defaults to null.
+ *
+ * @return mixed $default if the var is in user input or not present,
+ * the variable value otherwise.
+ */
+ static public function nonInputVar($varname, $default = null)
+ {
+ return (isset($_GET[$varname]) || isset($_POST[$varname]) || isset($_COOKIE[$varname]))
+ ? $default
+ : isset($GLOBALS[$varname]) ? $GLOBALS[$varname] : $default;
+ }
+
+ /**
+ * Adds a name=value pair to the end of an URL, taking care of whether
+ * there are existing parameters and whether to use ?, & or & as the
+ * glue. All data will be urlencoded.
+ *
+ * @param string $url The URL to modify
+ * @param mixed $parameter Either the name value -or- an array of
+ * name/value pairs.
+ * @param string $value If specified, the value part ($parameter is
+ * then assumed to just be the parameter name).
+ * @param boolean $encode Encode the argument separator?
+ *
+ * @return string The modified URL.
+ */
+ static public function addParameter($url, $parameter, $value = null,
+ $encode = true)
+ {
+ if (empty($parameter)) {
+ return $url;
+ }
+
+ $add = array();
+ $arg = $encode ? '&' : '&';
+
+ if (strpos($url, '?') !== false) {
+ list($url, $query) = explode('?', $url);
+
+ /* Check if the argument separator has been already
+ * htmlentities-ized in the URL. */
+ if (preg_match('/=.*?&.*?=/', $query)) {
+ $query = html_entity_decode($query);
+ $arg = '&';
+ } elseif (preg_match('/=.*?&.*?=/', $query)) {
+ $arg = '&';
+ }
+ $pairs = explode('&', $query);
+ foreach ($pairs as $pair) {
+ $pair = explode('=', urldecode($pair), 2);
+ $pair_val = (count($pair) == 2) ? $pair[1] : '';
+ if (substr($pair[0], -2) == '[]') {
+ $name = substr($pair[0], 0, -2);
+ if (!isset($add[$name])) {
+ $add[$name] = array();
+ }
+ $add[$name][] = $pair_val;
+ } else {
+ $add[$pair[0]] = $pair_val;
+ }
+ }
+ }
+
+ if (is_array($parameter)) {
+ $add = array_merge($add, $parameter);
+ } else {
+ $add[$parameter] = $value;
+ }
+
+ $url_params = array();
+ foreach ($add as $parameter => $value) {
+ if (is_array($value)) {
+ foreach ($value as $val) {
+ $url_params[] = urlencode($parameter) . '[]=' . urlencode($val);
+ }
+ } else {
+ $url_params[] = urlencode($parameter) . '=' . urlencode($value);
+ }
+ }
+
+ return count($url_params)
+ ? $url . '?' . implode($arg, $url_params)
+ : $url;
+ }
+
+ /**
+ * Removes name=value pairs from a URL.
+ *
+ * @param string $url The URL to modify.
+ * @param mixed $remove Either a single parameter to remove or an array
+ * of parameters to remove.
+ *
+ * @return string The modified URL.
+ */
+ static public function removeParameter($url, $remove)
+ {
+ if (!is_array($remove)) {
+ $remove = array($remove);
+ }
+
+ /* Return immediately if there are no parameters to remove. */
+ if (($pos = strpos($url, '?')) === false) {
+ return $url;
+ }
+
+ $entities = false;
+ list($url, $query) = explode('?', $url, 2);
+
+ /* Check if the argument separator has been already
+ * htmlentities-ized in the URL. */
+ if (preg_match('/=.*?&.*?=/', $query)) {
+ $entities = true;
+ $query = html_entity_decode($query);
+ }
+
+ /* Get the list of parameters. */
+ $pairs = explode('&', $query);
+ $params = array();
+ foreach ($pairs as $pair) {
+ $pair = explode('=', $pair, 2);
+ $params[$pair[0]] = count($pair) == 2 ? $pair[1] : '';
+ }
+
+ /* Remove the parameters. */
+ foreach ($remove as $param) {
+ unset($params[$param]);
+ }
+
+ if (!count($params)) {
+ return $url;
+ }
+
+ /* Flatten arrays.
+ * FIXME: should handle more than one array level somehow. */
+ $add = array();
+ foreach ($params as $key => $val) {
+ if (is_array($val)) {
+ foreach ($val as $v) {
+ $add[] = $key . '[]=' . $v;
+ }
+ } else {
+ $add[] = $key . '=' . $val;
+ }
+ }
+
+ $query = implode('&', $add);
+ if ($entities) {
+ $query = htmlentities($query);
+ }
+
+ return $url . '?' . $query;
+ }
+
+ /**
+ * Returns a url with the 'nocache' parameter added, if the browser is
+ * buggy and caches old URLs.
+ *
+ * @param string $url The URL to modify.
+ * @param boolean $encode Encode the argument separator?
+ *
+ * @return string The requested URI.
+ */
+ static public function nocacheUrl($url, $encode = true)
+ {
+ /* We may need to set a dummy parameter 'nocache' since some
+ * browsers do not always honor the 'no-cache' header. */
+ $browser = &Horde_Browser::singleton();
+ if ($browser->hasQuirk('cache_same_url')) {
+ if (is_null(self::$randnum)) {
+ self::$_randnum = base_convert(microtime(), 10, 36);
+ }
+ return self::addParameter($url, 'nocache', self::$_randnum, $encode);
+ }
+
+ return $url;
+ }
+
+ /**
+ * Returns a hidden form input containing the session name and id.
+ *
+ * @param boolean $append_session 0 = only if needed, 1 = always.
+ *
+ * @return string The hidden form input, if needed/requested.
+ */
+ static public function formInput($append_session = 0)
+ {
+ return (($append_session == 1) || !isset($_COOKIE[session_name()]))
+ ? '<input type="hidden" name="' . htmlspecialchars(session_name()) . '" value="' . htmlspecialchars(session_id()) . "\" />\n"
+ : '';
+ }
+
+ /**
+ * Prints a hidden form input containing the session name and id.
+ *
+ * @param boolean $append_session 0 = only if needed, 1 = always.
+ */
+ static public function pformInput($append_session = 0)
+ {
+ echo self::formInput($append_session);
+ }
+
+ /**
+ * If magic_quotes_gpc is in use, run stripslashes() on $var.
+ *
+ * @param string &$var The string to un-quote, if necessary.
+ *
+ * @return string $var, minus any magic quotes.
+ */
+ static public function dispelMagicQuotes(&$var)
+ {
+ if (is_null(self::$_magicquotes)) {
+ self::$_magicquotes = get_magic_quotes_gpc();
+ }
+
+ if (self::$_magicquotes) {
+ if (!is_array($var)) {
+ $var = stripslashes($var);
+ } else {
+ array_walk($var, array('Horde_Util', 'dispelMagicQuotes'));
+ }
+ }
+
+ return $var;
+ }
+
+ /**
+ * Gets a form variable from GET or POST data, stripped of magic quotes if
+ * necessary. If the variable is somehow set in both the GET data and the
+ * POST data, the value from the POST data will be returned and the GET
+ * value will be ignored.
+ *
+ * @param string $var The name of the form variable to look for.
+ * @param string $default The value to return if the variable is not
+ * there.
+ *
+ * @return string The cleaned form variable, or $default.
+ */
+ static public function getFormData($var, $default = null)
+ {
+ return (($val = self::getPost($var)) !== null)
+ ? $val
+ : self::getGet($var, $default);
+ }
+
+ /**
+ * Gets a form variable from GET data, stripped of magic quotes if
+ * necessary. This function will NOT return a POST variable.
+ *
+ * @param string $var The name of the form variable to look for.
+ * @param string $default The value to return if the variable is not
+ * there.
+ *
+ * @return string The cleaned form variable, or $default.
+ */
+ static public function getGet($var, $default = null)
+ {
+ return (isset($_GET[$var]))
+ ? self::dispelMagicQuotes($_GET[$var])
+ : $default;
+ }
+
+ /**
+ * Gets a form variable from POST data, stripped of magic quotes if
+ * necessary. This function will NOT return a GET variable.
+ *
+ * @param string $var The name of the form variable to look for.
+ * @param string $default The value to return if the variable is not
+ * there.
+ *
+ * @return string The cleaned form variable, or $default.
+ */
+ static public function getPost($var, $default = null)
+ {
+ return (isset($_POST[$var]))
+ ? self::dispelMagicQuotes($_POST[$var])
+ : $default;
+ }
+
+ /**
+ * Determines the location of the system temporary directory.
+ *
+ * @return string A directory name which can be used for temp files.
+ * Returns false if one could not be found.
+ */
+ static public function getTempDir()
+ {
+ /* First, try PHP's upload_tmp_dir directive. */
+ $tmp = ini_get('upload_tmp_dir');
+
+ /* Otherwise, try to determine the TMPDIR environment
+ * variable. */
+ if (empty($tmp)) {
+ $tmp = getenv('TMPDIR');
+ }
+
+ /* If we still cannot determine a value, then cycle through a
+ * list of preset possibilities. */
+ $tmp_locations = array('/tmp', '/var/tmp', 'c:\WUTemp', 'c:\temp',
+ 'c:\windows\temp', 'c:\winnt\temp');
+ while (empty($tmp) && count($tmp_locations)) {
+ $tmp_check = array_shift($tmp_locations);
+ if (@is_dir($tmp_check)) {
+ $tmp = $tmp_check;
+ }
+ }
+
+ /* If it is still empty, we have failed, so return false;
+ * otherwise return the directory determined. */
+ return empty($tmp) ? false : $tmp;
+ }
+
+ /**
+ * Creates a temporary filename for the lifetime of the script, and
+ * (optionally) register it to be deleted at request shutdown.
+ *
+ * @param string $prefix Prefix to make the temporary name more
+ * recognizable.
+ * @param boolean $delete Delete the file at the end of the request?
+ * @param string $dir Directory to create the temporary file in.
+ * @param boolean $secure If deleting file, should we securely delete the
+ * file?
+ *
+ * @return string Returns the full path-name to the temporary file.
+ * Returns false if a temp file could not be created.
+ */
+ static public function getTempFile($prefix = '', $delete = true, $dir = '',
+ $secure = false)
+ {
+ $tmp_dir = (empty($dir) || !is_dir($dir))
+ ? self::getTempDir()
+ : $dir;
+
+ if (empty($tmp_dir)) {
+ return false;
+ }
+
+ $tmp_file = tempnam($tmp_dir, $prefix);
+
+ /* If the file was created, then register it for deletion and
+ * return. */
+ if (empty($tmp_file)) {
+ return false;
+ }
+
+ if ($delete) {
+ self::deleteAtShutdown($tmp_file, true, $secure);
+ }
+
+ return $tmp_file;
+ }
+
+ /**
+ * Creates a temporary directory in the system's temporary directory.
+ *
+ * @param boolean $delete Delete the temporary directory at the end of
+ * the request?
+ * @param string $temp_dir Use this temporary directory as the directory
+ * where the temporary directory will be created.
+ *
+ * @return string The pathname to the new temporary directory.
+ * Returns false if directory not created.
+ */
+ static public function createTempDir($delete = true, $temp_dir = null)
+ {
+ if (is_null($temp_dir)) {
+ $temp_dir = self::getTempDir();
+ }
+
+ if (empty($temp_dir)) {
+ return false;
+ }
+
+ /* Get the first 8 characters of a random string to use as a temporary
+ directory name. */
+ do {
+ $new_dir = $temp_dir . '/' . substr(base_convert(mt_rand() . microtime(), 10, 36), 0, 8);
+ } while (file_exists($new_dir));
+
+ $old_umask = umask(0000);
+ if (!mkdir($new_dir, 0700)) {
+ $new_dir = false;
+ } elseif ($delete) {
+ self::deleteAtShutdown($new_dir);
+ }
+ umask($old_umask);
+
+ return $new_dir;
+ }
+
+ /**
+ * Returns the canonical path of the string. Like PHP's built-in
+ * realpath() except the directory need not exist on the local server.
+ *
+ * Algorithim loosely based on code from the Perl File::Spec::Unix module
+ * (version 1.5).
+ *
+ * @param string $path A file path.
+ *
+ * @return string The canonicalized file path.
+ */
+ static public function realPath($path)
+ {
+ /* Standardize on UNIX directory separators. */
+ if (!strncasecmp(PHP_OS, 'WIN', 3)) {
+ $path = str_replace('\\', '/', $path);
+ }
+
+ /* xx////xx -> xx/xx
+ * xx/././xx -> xx/xx */
+ $path = preg_replace(array("|/+|", "@(/\.)+(/|\Z(?!\n))@"), array('/', '/'), $path);
+
+ /* ./xx -> xx */
+ if ($path != './') {
+ $path = preg_replace("|^(\./)+|", '', $path);
+ }
+
+ /* /../../xx -> xx */
+ $path = preg_replace("|^/(\.\./?)+|", '/', $path);
+
+ /* xx/ -> xx */
+ if ($path != '/') {
+ $path = preg_replace("|/\Z(?!\n)|", '', $path);
+ }
+
+ /* /xx/.. -> / */
+ while (strpos($path, '/..') !== false) {
+ $path = preg_replace("|/[^/]+/\.\.|", '', $path);
+ }
+
+ return empty($path) ? '/' : $path;
+ }
+
+ /**
+ * Removes given elements at request shutdown.
+ *
+ * If called with a filename will delete that file at request shutdown; if
+ * called with a directory will remove that directory and all files in that
+ * directory at request shutdown.
+ *
+ * If called with no arguments, return all elements to be deleted (this
+ * should only be done by Horde_Util::_deleteAtShutdown()).
+ *
+ * The first time it is called, it initializes the array and registers
+ * Horde_Util::_deleteAtShutdown() as a shutdown function - no need to do
+ * so manually.
+ *
+ * The second parameter allows the unregistering of previously registered
+ * elements.
+ *
+ * @param string $filename The filename to be deleted at the end of the
+ * request.
+ * @param boolean $register If true, then register the element for
+ * deletion, otherwise, unregister it.
+ * @param boolean $secure If deleting file, should we securely delete
+ * the file?
+ */
+ static public function deleteAtShutdown($filename, $register = true,
+ $secure = false)
+ {
+ /* Initialization of variables and shutdown functions. */
+ if (!self::$_shutdownreg) {
+ register_shutdown_function(array('Horde_Util', 'shutdown'));
+ self::$_shutdownreg = true;
+ }
+
+ $ptr = &self::$_shutdowndata;
+ if ($register) {
+ if (@is_dir($filename)) {
+ $ptr['dirs'][$filename] = true;
+ } else {
+ $ptr['files'][$filename] = true;
+ }
+
+ if ($secure) {
+ $ptr['secure'][$filename] = true;
+ }
+ } else {
+ unset($ptr['dirs'][$filename], $ptr['files'][$filename], $ptr['secure'][$filename]);
+ }
+ }
+
+ /**
+ * Deletes registered files at request shutdown.
+ *
+ * This function should never be called manually; it is registered as a
+ * shutdown function by Horde_Util::deleteAtShutdown() and called
+ * automatically at the end of the request.
+ *
+ * Contains code from gpg_functions.php.
+ * Copyright 2002-2003 Braverock Ventures
+ */
+ static public function shutdown()
+ {
+ $ptr = &self::$_shutdowndata;
+
+ foreach ($ptr['files'] as $file => $val) {
+ /* Delete files */
+ if ($val && file_exists($file)) {
+ /* Should we securely delete the file by overwriting the data
+ with a random string? */
+ if (isset($ptr['secure'][$file])) {
+ $filesize = filesize($file);
+ $fp = fopen($file, 'r+');
+ foreach (self::$patterns as $pattern) {
+ $pattern = substr(str_repeat($pattern, floor($filesize / strlen($pattern)) + 1), 0, $filesize);
+ fwrite($fp, $pattern);
+ fseek($fp, 0);
+ }
+ fclose($fp);
+ }
+ @unlink($file);
+ }
+ }
+
+ foreach ($ptr['dirs'] as $dir => $val) {
+ /* Delete directories */
+ if ($val && file_exists($dir)) {
+ /* Make sure directory is empty. */
+ $dir_class = dir($dir);
+ while (false !== ($entry = $dir_class->read())) {
+ if ($entry != '.' && $entry != '..') {
+ @unlink($dir . '/' . $entry);
+ }
+ }
+ $dir_class->close();
+ @rmdir($dir);
+ }
+ }
+ }
+
+ /**
+ * Outputs javascript code to close the current window.
+ *
+ * @param string $code Any additional javascript code to run before
+ * closing the window.
+ */
+ static public function closeWindowJS($code = '')
+ {
+ echo '<script type="text/javascript">//<![CDATA[' . "\n"
+ . $code . 'window.close();' . "\n//]]></script>\n";
+ }
+
+ /**
+ * Caches the result of extension_loaded() calls.
+ *
+ * @param string $ext The extension name.
+ *
+ * @return boolean Is the extension loaded?
+ */
+ static public function extensionExists($ext)
+ {
+ if (!isset(self::$_cache[$ext])) {
+ self::$_cache[$ext] = extension_loaded($ext);
+ }
+
+ return self::$_cache[$ext];
+ }
+
+ /**
+ * Tries to load a PHP extension, behaving correctly for all operating
+ * systems.
+ *
+ * @param string $ext The extension to load.
+ *
+ * @return boolean True if the extension is now loaded, false if not.
+ * True can mean that the extension was already loaded,
+ * OR was loaded dynamically.
+ */
+ static public function loadExtension($ext)
+ {
+ /* If $ext is already loaded, our work is done. */
+ if (self::extensionExists($ext)) {
+ return true;
+ }
+
+ /* See if we can call dl() at all, by the current ini settings. */
+ if ((ini_get('enable_dl') != 1) || (ini_get('safe_mode') == 1)) {
+ return false;
+ }
+
+ if (!strncasecmp(PHP_OS, 'WIN', 3)) {
+ $suffix = 'dll';
+ } else {
+ switch (PHP_OS) {
+ case 'HP-UX':
+ $suffix = 'sl';
+ break;
+
+ case 'AIX':
+ $suffix = 'a';
+ break;
+
+ case 'OSX':
+ $suffix = 'bundle';
+ break;
+
+ default:
+ $suffix = 'so';
+ }
+ }
+
+ return @dl($ext . '.' . $suffix) || @dl('php_' . $ext . '.' . $suffix);
+ }
+
+ /**
+ * Checks if all necessary parameters for a driver's configuration are set
+ * and returns a PEAR_Error if something is missing.
+ *
+ * @param array $params The configuration array with all parameters.
+ * @param array $fields An array with mandatory parameter names for this
+ * driver.
+ * @param string $name The clear text name of the driver. If not
+ * specified, the application name will be used.
+ * @param array $info A hash containing detailed information about the
+ * driver. Will be passed as the userInfo to the
+ * PEAR_Error.
+ */
+ static public function assertDriverConfig($params, $fields, $name,
+ $info = array())
+ {
+ $info = array_merge($info, array(
+ 'params' => $params,
+ 'fields' => $fields,
+ 'name' => $name
+ ));
+
+ if (!is_array($params) || !count($params)) {
+ return PEAR::throwError(sprintf(_("No configuration information specified for %s."), $name), self::HORDE_ERROR_DRIVER_CONFIG_MISSING, $info);
+ }
+
+ foreach ($fields as $field) {
+ if (!isset($params[$field])) {
+ return PEAR::throwError(sprintf(_("Required \"%s\" not specified in configuration."), $field, $name), self::HORDE_ERROR_DRIVER_CONFIG, $info);
+ }
+ }
+ }
+
+ /**
+ * Returns a format string to be used by strftime().
+ *
+ * @param string $format A format string as used by date().
+ *
+ * @return string A format string as similar as possible to $format.
+ */
+ static public function date2strftime($format)
+ {
+ $result = '';
+
+ for ($pos = 0; $pos < strlen($format);) {
+ for ($symbol = 0, $symcount = count(self::$dateSymbols); $symbol < $symcount; ++$symbol) {
+ if (strpos($format, self::$dateSymbols[$symbol], $pos) === $pos) {
+ $result .= self::$strftimeSymbols[$symbol];
+ $pos += strlen(self::$dateSymbols[$symbol]);
+ continue 2;
+ }
+ }
+ $result .= substr($format, $pos, 1);
+ ++$pos;
+ }
+
+ return $result;
+ }
+
+ /**
+ * Returns a format string to be used by date().
+ *
+ * @param string $format A format string as used by strftime().
+ *
+ * @return string A format string as similar as possible to $format.
+ */
+ static public function strftime2date($format)
+ {
+ return str_replace(self::$strftimeSymbols, self::$dateSymbols, $format);
+ }
+
+ /**
+ * Utility function to obtain PATH_INFO information.
+ *
+ * @return string The PATH_INFO string.
+ */
+ static public function getPathInfo()
+ {
+ if (isset($_SERVER['PATH_INFO']) && strpos($_SERVER['SERVER_SOFTWARE'], 'lighttpd') === false) {
+ return $_SERVER['PATH_INFO'];
+ } elseif (isset($_SERVER['REQUEST_URI']) &&
+ isset($_SERVER['SCRIPT_NAME'])) {
+ $search = array($_SERVER['SCRIPT_NAME']);
+ $replace = array('');
+ if (!empty($_SERVER['QUERY_STRING'])) {
+ $search[] = '?' . $_SERVER['QUERY_STRING'];
+ $replace[] = '';
+ }
+ return str_replace($search, $replace, $_SERVER['REQUEST_URI']);
+ }
+
+ return '';
+ }
+
+ /**
+ * URL-safe base64 encoding, with trimmed '='.
+ *
+ * @param string $string String to encode.
+ *
+ * @return string URL-safe, base64 encoded data.
+ */
+ static public function uriB64Encode($string)
+ {
+ return str_replace(array('+', '/', '='), array('-', '_', ''), base64_encode($string));
+ }
+
+ /**
+ * Decode URL-safe base64 data, dealing with missing '='.
+ *
+ * @param string $string Encoded data
+ *
+ * @return string Decoded data.
+ */
+ static public function uriB64Decode($string)
+ {
+ $data = str_replace(array('-', '_'), array('+', '/'), $string);
+ $mod4 = strlen($data) % 4;
+ if ($mod4) {
+ $data .= substr('====', $mod4);
+ }
+ return base64_decode($data);
+ }
+
+}
+
+/* Stand-in functions if gettext is not available. */
+if (!function_exists('_'))
+{
+ function _($string)
+ {
+ return $string;
+ }
+
+ function ngettext($msgid1, $msgid2, $n)
+ {
+ return $n > 1 ? $msgid2 : $msgid1;
+ }
+
+ function bindtextdomain() { }
+
+ function textdomain() { }
+}
--- /dev/null
+<?php
+/**
+ * Horde_Variables:: class.
+ *
+ * Copyright 2009 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * @author Robert E. Coyle <robertecoyle@hotmail.com>
+ * @author Chuck Hagenbuch <chuck@horde.org>
+ * @package Horde_Util
+ */
+class Horde_Variables
+{
+ /**
+ * TODO
+ */
+ protected $_vars;
+
+ /**
+ * TODO
+ */
+ protected $_expectedVariables = array();
+
+ /**
+ * TODO
+ */
+ public function __construct($vars = array())
+ {
+ if (is_null($vars)) {
+ $vars = Horde_Util::dispelMagicQuotes($_REQUEST);
+ }
+
+ if (isset($vars['_formvars'])) {
+ $this->_expectedVariables = @unserialize($vars['_formvars']);
+ unset($vars['_formvars']);
+ }
+
+ $this->_vars = $vars;
+ }
+
+ /**
+ * TODO
+ */
+ public function &getDefaultVariables()
+ {
+ $vars = new Variables(null);
+ return $vars;
+ }
+
+ /**
+ * TODO
+ */
+ public function count()
+ {
+ return count($this->_vars);
+ }
+
+ /**
+ * TODO
+ */
+ public function exists($varname)
+ {
+ return $this->__isset($varname);
+ }
+
+ /**
+ * TODO
+ */
+ public function __isset($varname)
+ {
+ if (count($this->_expectedVariables) &&
+ $this->_exists($this->_expectedVariables, $varname, false)) {
+ return true;
+ }
+
+ return $this->_exists($this->_vars, $varname, false);
+ }
+
+ /**
+ * TODO
+ */
+ public function get($varname)
+ {
+ return $this->__get($varname);
+ }
+
+ /**
+ * TODO
+ */
+ public function __get($varname)
+ {
+ $this->_getExists($this->_vars, $varname, $value);
+ return $value;
+ }
+
+ /**
+ * TODO
+ */
+ public function getExists($varname, &$exists)
+ {
+ $exists = $this->_getExists($this->_vars, $varname, $value);
+ return $value;
+ }
+
+ /**
+ * TODO
+ */
+ public function set($varname, $value)
+ {
+ return $this->__set($varname, $value);
+ }
+
+ /**
+ * TODO
+ */
+ public function __set($varname, $value)
+ {
+ $keys = array();
+ if (!Horde_Array::getArrayParts($varname, $base, $keys)) {
+ $this->_vars[$varname] = $value;
+ } else {
+ array_unshift($keys, $base);
+ $place = &$this->_vars;
+
+ while (count($keys)) {
+ $key = array_shift($keys);
+ if (!isset($place[$key])) {
+ $place[$key] = array();
+ }
+ $place = &$place[$key];
+ }
+
+ $place = $value;
+ }
+ }
+
+ /**
+ * TODO
+ */
+ public function remove($varname)
+ {
+ return $this->__unset($varname);
+ }
+
+ /**
+ * TODO
+ */
+ public function __unset($varname)
+ {
+ Horde_Array::getArrayParts($varname, $base, $keys);
+ if (!is_null($base)) {
+ $ptr = &$this->_vars[$base];
+ $end = count($keys) - 1;
+ foreach ($keys as $key => $val) {
+ if (!isset($ptr[$val])) {
+ break;
+ }
+ if ($end == $key) {
+ array_splice($ptr, array_search($val, array_keys($ptr)), 1);
+ } else {
+ $ptr = &$ptr[$val];
+ }
+ }
+ } else {
+ unset($this->_vars[$varname]);
+ }
+ }
+
+ /**
+ * TODO
+ */
+ public function merge($vars)
+ {
+ foreach ($vars as $varname => $value) {
+ $this->set($varname, $value);
+ }
+ }
+
+ /**
+ * Set $varname to $value ONLY if it's not already present.
+ */
+ public function add($varname, $value)
+ {
+ if ($this->exists($varname)) {
+ return false;
+ }
+ $this->_vars[$varname] = $value;
+ }
+
+ /**
+ * Find out whether or not $varname was set in $array.
+ *
+ * @param array $array The array to search in (usually either
+ * $this->_vars or $this->_expectedVariables).
+ * @param string $varname The name of the variable to look for.
+ * @param boolean $check If we don't find $varname, should we check
+ * $this->_expectedVariables to see if should
+ * have existed (like a checkbox or select
+ * multiple).
+ *
+ * @return boolean Whether or not the variable was set (or, if we've
+ * checked $this->_expectedVariables, should have been
+ * set).
+ */
+ protected function _exists($array, $varname, $check = true)
+ {
+ return $this->_getExists($array, $varname, $value, $check);
+ }
+
+ /**
+ * Fetch the requested variable ($varname) into $value, and return
+ * whether or not the variable was set in $array.
+ *
+ * @param array $array The array to search in (usually either
+ * $this->_vars or $this->_expectedVariables).
+ * @param string $varname The name of the variable to look for.
+ * @param mixed &$value $varname's value gets assigned to this variable.
+ * @param boolean $check If we don't find $varname, should we check
+ * $this->_expectedVariables to see if should
+ * have existed (like a checkbox or select
+ * multiple).
+ *
+ * @return boolean Whether or not the variable was set (or, if we've
+ * checked $this->_expectedVariables, should have been
+ * set).
+ */
+ protected function _getExists($array, $varname, &$value, $check = true)
+ {
+ if (Horde_Array::getArrayParts($varname, $base, $keys)) {
+ if (!isset($array[$base])) {
+ $value = null;
+ // If we're supposed to check $this->_expectedVariables, do so,
+ // but make sure not to check it again.
+ return $check
+ ? $this->_exists($this->_expectedVariables, $varname, false)
+ : false;
+ } else {
+ $searchspace = &$array[$base];
+ while (count($keys)) {
+ $key = array_shift($keys);
+ if (!isset($searchspace[$key])) {
+ $value = null;
+ // If we're supposed to check
+ // $this->_expectedVariables, do so, but make
+ // sure not to check it again.
+ return $check
+ ? $this->_exists($this->_expectedVariables, $varname, false)
+ : false;
+ }
+ $searchspace = &$searchspace[$key];
+ }
+ $value = $searchspace;
+ return true;
+ }
+ } else {
+ $value = isset($array[$varname]) ? $array[$varname] : null;
+ if (!is_null($value)) {
+ return true;
+ } elseif ($check) {
+ // If we're supposed to check
+ // $this->_expectedVariables, do so, but make sure not
+ // to check it again.
+ return $this->_exists($this->_expectedVariables, $varname, false);
+ } else {
+ return false;
+ }
+ }
+ }
+
+}
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<package packagerversion="1.4.9" version="2.0" xmlns="http://pear.php.net/dtd/package-2.0" xmlns:tasks="http://pear.php.net/dtd/tasks-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0
+http://pear.php.net/dtd/tasks-1.0.xsd
+http://pear.php.net/dtd/package-2.0
+http://pear.php.net/dtd/package-2.0.xsd">
+ <name>Util</name>
+ <channel>pear.horde.org</channel>
+ <summary>Horde Utility Libraries</summary>
+ <description>These classes provide functionality useful for all kind of applications.</description>
+ <lead>
+ <name>Chuck Hagenbuch</name>
+ <user>chuck</user>
+ <email>chuck@horde.org</email>
+ <active>yes</active>
+ </lead>
+ <lead>
+ <name>Jan Schneider</name>
+ <user>jan</user>
+ <email>jan@horde.org</email>
+ <active>yes</active>
+ </lead>
+ <date>2009-06-09</date>
+ <version>
+ <release>0.2.0</release>
+ <api>0.2.0</api>
+ </version>
+ <stability>
+ <release>beta</release>
+ <api>beta</api>
+ </stability>
+ <license uri="http://www.gnu.org/copyleft/lesser.html">LGPL</license>
+ <notes>* Removed Horde_Array::combine() and Horde_Util::hmac().
+ * Initial Horde 4 package.
+ </notes>
+ <contents>
+ <dir name="/">
+ <dir name="lib">
+ <dir name="Horde">
+ <dir name="Array">
+ <dir name="Sort">
+ <file name="Helper.php" role="php" />
+ </dir> <!-- /lib/Horde/Array/Sort -->
+ </dir> <!-- /lib/Horde/Array -->
+ <file name="Array.php" role="php" />
+ <file name="String.php" role="php" />
+ <file name="Util.php" role="php" />
+ <file name="Variables.php" role="php" />
+ </dir> <!-- /lib/Horde -->
+ </dir> <!-- /lib -->
+ <dir name="test">
+ <dir name="Horde">
+ <dir name="Util">
+ <file name="Array_sort.phpt" role="test" />
+ <file name="Variables_remove.phpt" role="test" />
+ <file name="addParameter.phpt" role="test" />
+ <file name="case.phpt" role="test" />
+ <file name="case_php6.phpt" role="test" />
+ <file name="length.phpt" role="test" />
+ <file name="pad.phpt" role="test" />
+ <file name="removeParameter.phpt" role="test" />
+ <file name="utf-8.phpt" role="test" />
+ </dir> <!-- /test/Horde/Util -->
+ </dir> <!-- /test/Horde -->
+ </dir> <!-- /test -->
+ </dir> <!-- / -->
+ </contents>
+ <dependencies>
+ <required>
+ <php>
+ <min>5.2.0</min>
+ </php>
+ <pearinstaller>
+ <min>1.5.4</min>
+ </pearinstaller>
+ </required>
+ <optional>
+ <package>
+ <name>PEAR</name>
+ <channel>pear.php.net</channel>
+ </package>
+ <package>
+ <name>Horde_Browser</name>
+ <channel>pear.horde.org</channel>
+ </package>
+ <extension>
+ <name>iconv</name>
+ </extension>
+ <extension>
+ <name>mbstring</name>
+ </extension>
+ </optional>
+ </dependencies>
+ <phprelease>
+ <filelist>
+ <install name="lib/Horde/Array.php" as="Horde/Array.php" />
+ <install name="lib/Horde/Array/Sort/Helper.php" as="Horde/Array/Sort/Helper.php" />
+ <install name="lib/Horde/String.php" as="Horde/String.php" />
+ <install name="lib/Horde/Util.php" as="Horde/Util.php" />
+ <install name="lib/Horde/Variables.php" as="Horde/Variables.php" />
+ </filelist>
+ </phprelease>
+ <changelog>
+ <release>
+ <version>
+ <release>0.1.0</release>
+ <api>0.1.0</api>
+ </version>
+ <date>2008-09-25</date>
+ <stability>
+ <release>beta</release>
+ <api>beta</api>
+ </stability>
+ <license uri="http://www.gnu.org/copyleft/lesser.html">LGPL</license>
+ <notes>* Added magic PHP5 methods to the Variables class.
+* Added array_merge_recursive_overwrite() to Horde_Array().
+* Fixed a bug in Horde_Array::arraySort where auto-detecting the first key failed.
+* Added sorter functions for array keys.
+* Removed use of array_unique().
+* Cleaned up addParameter() in the Util class.
+* Implemented a much more efficient, yet safer file wiping algorithm.
+* Fixed Util::addParameter when it is passed a base URL that contains an urlencoded ampersand.
+* Added a parameter to Util::nocacheUrl() to not encode url.
+* Added Util::getPathInfo().
+* Signed parameters to go.php with an HMAC based on a new secret key configuration value, to prevent using go.php as an open referrer.
+* Made logout tokens only valid for a configurable length of time.
+* Made it possible to use String.php without having any other files available.
+* Use utf8_decode() in String::length() if possible.
+* Always use preg_match() in String::regexMatch().
+* Workaround for korean messages in a non-standard charset.
+* Fixed String::substr() length calculations.
+* Added multibyte-safe String::wordwrap() method.
+* Added parameter to use wordwrap() for line folding.
+* Use C as the portable locale (Bug #6194).
+* Don't use utf8_encode/decode on very large strings if other options are available. (Bug #6660)
+* Fixed order of checks in String::convertCharset (Bug #6794).
+ </notes>
+ </release>
+ <release>
+ <version>
+ <release>0.0.2</release>
+ <api>0.0.2</api>
+ </version>
+ <stability>
+ <release>alpha</release>
+ <api>alpha</api>
+ </stability>
+ <date>2006-05-08</date>
+ <license uri="http://www.gnu.org/copyleft/lesser.html">LGPL</license>
+ <notes>Converted to package.xml 2.0 for pear.horde.org
+ </notes>
+ </release>
+ <release>
+ <version>
+ <release>0.0.1</release>
+ <api>0.0.1</api>
+ </version>
+ <stability>
+ <release>alpha</release>
+ <api>alpha</api>
+ </stability>
+ <date>2003-10-28</date>
+ <license uri="http://www.gnu.org/copyleft/lesser.html">LGPL</license>
+ <notes>Initial release as a PEAR package
+ </notes>
+ </release>
+ </changelog>
+</package>
--- /dev/null
+--TEST--
+Horde_Array::arraySort() tests
+--FILE--
+<?php
+
+require dirname(__FILE__) . '/../Array.php';
+$array = array(
+ array('name' => 'foo', 'desc' => 'foo long desc'),
+ array('name' => 'aaaa', 'desc' => 'aaa foo long desc'),
+ array('name' => 'baby', 'desc' => 'The test data was boring'),
+ array('name' => 'zebra', 'desc' => 'Striped armadillos'),
+ array('name' => 'umbrage', 'desc' => 'resentment'),
+);
+
+Horde_Array::arraySort($array);
+print_r($array);
+
+Horde_Array::arraySort($array, 'desc');
+print_r($array);
+
+?>
+--EXPECT--
+Array
+(
+ [1] => Array
+ (
+ [name] => aaaa
+ [desc] => aaa foo long desc
+ )
+
+ [2] => Array
+ (
+ [name] => baby
+ [desc] => The test data was boring
+ )
+
+ [0] => Array
+ (
+ [name] => foo
+ [desc] => foo long desc
+ )
+
+ [4] => Array
+ (
+ [name] => umbrage
+ [desc] => resentment
+ )
+
+ [3] => Array
+ (
+ [name] => zebra
+ [desc] => Striped armadillos
+ )
+
+)
+Array
+(
+ [1] => Array
+ (
+ [name] => aaaa
+ [desc] => aaa foo long desc
+ )
+
+ [0] => Array
+ (
+ [name] => foo
+ [desc] => foo long desc
+ )
+
+ [4] => Array
+ (
+ [name] => umbrage
+ [desc] => resentment
+ )
+
+ [3] => Array
+ (
+ [name] => zebra
+ [desc] => Striped armadillos
+ )
+
+ [2] => Array
+ (
+ [name] => baby
+ [desc] => The test data was boring
+ )
+
+)
--- /dev/null
+--TEST--
+Variables::remove() tests
+--FILE--
+<?php
+
+require dirname(__FILE__) . '/../Variables.php';
+$vars = new Variables(array(
+ 'a' => 'a',
+ 'b' => 'b',
+ 'c' => array(1, 2, 3),
+ 'd' => array(
+ 'z' => 'z',
+ 'y' => array(
+ 'f' => 'f',
+ 'g' => 'g'
+ )
+ )
+));
+
+$vars->remove('a');
+$vars->remove('d[y][g]');
+print_r($vars->_vars);
+
+?>
+--EXPECT--
+Array
+(
+ [b] => b
+ [c] => Array
+ (
+ [0] => 1
+ [1] => 2
+ [2] => 3
+ )
+
+ [d] => Array
+ (
+ [z] => z
+ [y] => Array
+ (
+ [f] => f
+ )
+
+ )
+
+)
--- /dev/null
+--TEST--
+Horde_Util::addParameter() tests
+--FILE--
+<?php
+
+require_once dirname(__FILE__) . '/../../lib/Horde/Util.php';
+
+$url = 'test';
+echo ($url = Horde_Util::addParameter($url, 'foo', 1)) . "\n";
+echo ($url = Horde_Util::addParameter($url, 'bar', 2)) . "\n";
+echo Horde_Util::addParameter($url, 'baz', 3) . "\n";
+echo Horde_Util::addParameter('test', array('foo' => 1, 'bar' => 2)) . "\n";
+echo Horde_Util::addParameter('test?foo=1', array('bar' => 2, 'baz' => 3)) . "\n";
+echo Horde_Util::addParameter('test?foo=1&bar=2', array('baz' => 3)) . "\n";
+echo Horde_Util::addParameter('test?foo=1&bar=2', array('foo' => 1, 'bar' => 3)) . "\n";
+echo Horde_Util::addParameter('test?foo=1&bar=2', 'baz', 3) . "\n";
+echo ($url = Horde_Util::addParameter('test', 'foo', 'bar&baz')) . "\n";
+echo Horde_Util::addParameter($url, 'x', 'y') . "\n";
+echo Horde_Util::addParameter($url, 'x', 'y', false) . "\n";
+echo Horde_Util::addParameter(Horde_Util::addParameter('test', 'x', 'y'), 'foo', 'bar&baz') . "\n";
+
+?>
+--EXPECT--
+test?foo=1
+test?foo=1&bar=2
+test?foo=1&bar=2&baz=3
+test?foo=1&bar=2
+test?foo=1&bar=2&baz=3
+test?foo=1&bar=2&baz=3
+test?foo=1&bar=3
+test?foo=1&bar=2&baz=3
+test?foo=bar%26baz
+test?foo=bar%26baz&x=y
+test?foo=bar%26baz&x=y
+test?x=y&foo=bar%26baz
--- /dev/null
+--TEST--
+Horde_String:: case tests
+--SKIPIF--
+<?php
+if (!setlocale(LC_ALL, 'tr_TR')) echo 'skip No Turkish locale installed.';
+?>
+--FILE--
+<?php
+
+require_once dirname(__FILE__) . '/../../lib/Horde/Util.php';
+require_once dirname(__FILE__) . '/../../lib/Horde/String.php';
+
+echo Horde_String::upper('abCDefGHiI', true, 'us-ascii') . "\n";
+echo Horde_String::lower('abCDefGHiI', true, 'us-ascii') . "\n";
+echo "\n";
+echo Horde_String::upper('abCDefGHiI', true, 'Big5') . "\n";
+echo Horde_String::lower('abCDefGHiI', true, 'Big5') . "\n";
+echo "\n";
+setlocale(LC_ALL, 'tr_TR');
+echo strtoupper('abCDefGHiI') . "\n";
+echo strtolower('abCDefGHiI') . "\n";
+echo ucfirst('integer') . "\n";
+echo "\n";
+echo Horde_String::upper('abCDefGHiI') . "\n";
+echo Horde_String::lower('abCDefGHiI') . "\n";
+echo Horde_String::ucfirst('integer') . "\n";
+
+?>
+--EXPECT--
+ABCDEFGHII
+abcdefghii
+
+ABCDEFGHII
+abcdefghii
+
+ABCDEFGHÝI
+abcdefghiý
+Ýnteger
+
+ABCDEFGHII
+abcdefghii
+Integer
--- /dev/null
+--TEST--
+Horde_String:: case PHP 6 tests
+--SKIPIF--
+<?php
+if (version_compare(PHP_VERSION, '6.0', '<')) {
+ echo 'skip mbstring is broken in PHP < 6.0';
+}
+?>
+--FILE--
+<?php
+
+require_once dirname(__FILE__) . '/../../lib/Horde/Util.php';
+require_once dirname(__FILE__) . '/../../lib/Horde/String.php';
+
+echo Horde_String::upper('abCDefGHiI', true, 'iso-8859-9') . "\n";
+echo Horde_String::lower('abCDefGHiI', true, 'iso-8859-9') . "\n";
+echo "\n";
+echo Horde_String::ucfirst('integer', true, 'us-ascii') . "\n";
+echo Horde_String::ucfirst('integer', true, 'iso-8859-9') . "\n";
+
+?>
+--EXPECT--
+ABCDEFGHÝI
+abcdefghiý
+
+Integer
+Ýnteger
--- /dev/null
+--TEST--
+Horde_String::length() tests
+--FILE--
+<?php
+
+require_once dirname(__FILE__) . '/../../lib/Horde/Util.php';
+require_once dirname(__FILE__) . '/../../lib/Horde/String.php';
+
+echo Horde_String::length('Welcome', 'Big5'). "\n";
+echo Horde_String::length('Welcome', 'Big5'). "\n";
+echo Horde_String::length('Åwªï', 'Big5') . "\n";
+echo Horde_String::length('æ¡è¿å°', 'utf-8') . "\n";
+
+?>
+--EXPECT--
+7
+7
+2
+3
--- /dev/null
+--TEST--
+Horde_String::pad() tests
+--FILE--
+<?php
+
+require_once dirname(__FILE__) . '/../../lib/Horde/Util.php';
+require_once dirname(__FILE__) . '/../../lib/Horde/String.php';
+
+/* Simple single byte tests. */
+echo Horde_String::pad('abc', 2) . "\n";
+echo Horde_String::pad('abc', 3) . "\n";
+echo Horde_String::pad('abc', 4) . "\n";
+echo Horde_String::pad('abc', 4, ' ', STR_PAD_LEFT) . "\n";
+echo Horde_String::pad('abc', 4, ' ', STR_PAD_RIGHT) . "\n";
+echo Horde_String::pad('abc', 4, ' ', STR_PAD_BOTH) . "\n";
+echo Horde_String::pad('abc', 5, ' ', STR_PAD_LEFT) . "\n";
+echo Horde_String::pad('abc', 5, ' ', STR_PAD_RIGHT) . "\n";
+echo Horde_String::pad('abc', 5, ' ', STR_PAD_BOTH) . "\n";
+
+/* Long padding tests. */
+echo "\n";
+echo Horde_String::pad('abc', 10, '=-+', STR_PAD_LEFT) . "\n";
+echo Horde_String::pad('abc', 10, '=-+', STR_PAD_RIGHT) . "\n";
+echo Horde_String::pad('abc', 10, '=-+', STR_PAD_BOTH) . "\n";
+
+/* Multibyte tests. */
+echo "\n";
+echo Horde_String::pad('äöü', 4, ' ', STR_PAD_LEFT, 'UTF-8') . "\n";
+echo Horde_String::pad('äöü', 4, ' ', STR_PAD_RIGHT, 'UTF-8') . "\n";
+echo Horde_String::pad('äöü', 4, ' ', STR_PAD_BOTH, 'UTF-8') . "\n";
+echo "\n";
+echo Horde_String::pad('abc', 10, 'äöü', STR_PAD_LEFT, 'UTF-8') . "\n";
+echo Horde_String::pad('abc', 10, 'äöü', STR_PAD_RIGHT, 'UTF-8') . "\n";
+echo Horde_String::pad('abc', 10, 'äöü', STR_PAD_BOTH, 'UTF-8') . "\n";
+
+/* Special cases. */
+echo "\n";
+echo Horde_String::pad('abc', 4, ' ', STR_PAD_RIGHT, 'UTF-8') . "\n";
+
+
+?>
+--EXPECT--
+abc
+abc
+abc
+ abc
+abc
+abc
+ abc
+abc
+ abc
+
+=-+=-+=abc
+abc=-+=-+=
+=-+abc=-+=
+
+ äöü
+äöü
+äöü
+
+äöüäöüäabc
+abcäöüäöüä
+äöüabcäöüä
+
+abc
--- /dev/null
+--TEST--
+Horde_Util::removeParameter() tests
+--FILE--
+<?php
+
+require_once dirname(__FILE__) . '/../../lib/Horde/Util.php';
+
+$url = 'test?foo=1&bar=2';
+echo Horde_Util::removeParameter($url, 'foo') . "\n";
+echo Horde_Util::removeParameter($url, 'bar') . "\n";
+echo Horde_Util::removeParameter($url, array('foo', 'bar')) . "\n";
+$url = 'test?foo=1&bar=2';
+echo Horde_Util::removeParameter($url, 'foo') . "\n";
+echo Horde_Util::removeParameter($url, 'bar') . "\n";
+echo Horde_Util::removeParameter($url, array('foo', 'bar')) . "\n";
+$url = 'test?foo=1&bar=2&baz=3';
+echo Horde_Util::removeParameter($url, 'foo') . "\n";
+$url = 'test?foo=1&bar=2&baz=3';
+echo Horde_Util::removeParameter($url, 'foo') . "\n";
+
+?>
+--EXPECT--
+test?bar=2
+test?foo=1
+test
+test?bar=2
+test?foo=1
+test
+test?bar=2&baz=3
+test?bar=2&baz=3
--- /dev/null
+--TEST--
+Horde_String::substr() tests
+--FILE--
+<?php
+
+require_once dirname(__FILE__) . '/../../lib/Horde/Util.php';
+require_once dirname(__FILE__) . '/../../lib/Horde/String.php';
+
+$string = "Lörem ipsüm dölör sit ämet";
+echo Horde_String::substr($string, 20, null, 'UTF-8') . "\n";
+echo Horde_String::substr($string, -6, null, 'utf-8') . "\n";
+echo Horde_String::substr($string, 0, 5, 'utf-8') . "\n";
+echo Horde_String::substr($string, 0, -21, 'utf-8') . "\n";
+echo Horde_String::substr($string, 6, 5, 'utf-8') . "\n";
+
+?>
+--EXPECT--
+t ämet
+t ämet
+Lörem
+Lörem
+ipsüm
--- /dev/null
+--TEST--
+UTF-8 Horde_String:: tests
+--FILE--
+<?php
+
+require_once dirname(__FILE__) . '/../../lib/Horde/Util.php';
+require_once dirname(__FILE__) . '/../../lib/Horde/String.php';
+
+/* The following strings were taken with permission from the UTF-8
+ * sampler by Frank da Cruz <fdc@columbia.edu> and the Kermit Project
+ * (http://www.columbia.edu/kermit/). The original page is located at
+ * http://www.columbia.edu/kermit/utf8.html */
+
+// French 50
+echo Horde_String::length('Je peux manger du verre, ça ne me fait pas de mal.', 'UTF-8') . "\n";
+
+// Spanish 36
+echo Horde_String::length('Puedo comer vidrio, no me hace daño.', 'UTF-8') . "\n";
+
+// Portuguese 34
+echo Horde_String::length('Posso comer vidro, não me faz mal.', 'UTF-8') . "\n";
+
+// Brazilian Portuguese 34
+echo Horde_String::length('Posso comer vidro, não me machuca.', 'UTF-8') . "\n";
+
+// Italian 41
+echo Horde_String::length('Posso mangiare il vetro e non mi fa male.', 'UTF-8') . "\n";
+
+// English 39
+echo Horde_String::length('I can eat glass and it doesn\'t hurt me.', 'UTF-8') . "\n";
+
+// Norsk/Norwegian/Nynorsk 33
+echo Horde_String::length('Eg kan eta glas utan å skada meg.', 'UTF-8') . "\n";
+
+// Svensk/Swedish 36
+echo Horde_String::length('Jag kan äta glas utan att skada mig.', 'UTF-8') . "\n";
+
+// Dansk/Danish 45
+echo Horde_String::length('Jeg kan spise glas, det gør ikke ondt på mig.', 'UTF-8') . "\n";
+
+// Deutsch/German 41
+echo Horde_String::length('Ich kann Glas essen, ohne mir weh zu tun.', 'UTF-8') . "\n";
+
+// Russian 38
+echo Horde_String::length('Я могу есть стекло, оно мне не вредит.', 'UTF-8') . "\n";
+
+?>
+--EXPECT--
+50
+36
+34
+34
+41
+39
+33
+36
+45
+41
+38
--- /dev/null
+--TEST--
+Horde_String::wordwrap() tests
+--FILE--
+<?php
+
+require_once dirname(__FILE__) . '/../../lib/Horde/Util.php';
+require_once dirname(__FILE__) . '/../../lib/Horde/String.php';
+
+// Test default parameters and break character.
+$string = "Lörem ipsüm dölör sit ämet, cönsectetüer ädipiscing elit. Aliqüäm söllicitüdin fäücibüs mäüris ämet.";
+echo Horde_String::wordwrap($string, 75, "\n", false, 'utf-8') . "\n\n";
+echo Horde_String::wordwrap($string, 30, "\n ", false, 'utf-8') . "\n\n";
+
+// Test existing line breaks.
+$string = "Lörem ipsüm dölör sit ämet, cönsectetüer ädipiscing elit.\nAliqüäm söllicitüdin fäücibüs mäüris ämet.";
+echo Horde_String::wordwrap($string, 75, "\n", false, 'utf-8') . "\n\n";
+$string = "Lörem ipsüm dölör sit ämet, cönsectetüer ädipiscing elit. Aliqüäm\nsöllicitüdin fäücibüs mäüris ämet.";
+echo Horde_String::wordwrap($string, 75, "\n", false, 'utf-8') . "\n\n";
+$string = "Lörem ipsüm dölör sit ämet, cönsectetüer ädipiscing elit. Aliqüäm söllicitüdin\nfäücibüs mäüris ämet.";
+echo Horde_String::wordwrap($string, 75, "\n", false, 'utf-8') . "\n\n";
+
+// Test overlong words and word cut.
+$string = "Löremipsümdölörsitämet, cönsectetüerädipiscingelit.";
+echo Horde_String::wordwrap($string, 15, "\n", false, 'utf-8') . "\n\n";
+$string = "Löremipsümdölörsitämet, cönsectetüerädipiscingelit.";
+echo Horde_String::wordwrap($string, 15, "\n", true, 'utf-8') . "\n\n";
+
+// Test whitespace at wrap width.
+$string = "Lörem ipsüm dölör sit ämet, cönsectetüer ädipiscing";
+echo Horde_String::wordwrap($string, 27, "\n", false, 'utf-8') . "\n\n";
+echo Horde_String::wordwrap($string, 28, "\n", false, 'utf-8') . "\n\n";
+
+// Test line folding.
+$string = "Löremipsümdölörsitämet, cönsectetüerädipiscingelit.";
+echo Horde_String::wordwrap($string, 15, "\n", true, 'utf-8', true) . "\n\n";
+$string = "Lörem ipsüm dölör sit ämet, cönsectetüer ädipiscing elit. Aliqüäm söllicitüdin fäücibüs mäüris ämet.";
+echo Horde_String::wordwrap($string, 31, "\n", false, 'utf-8', true) . "\n\n";
+$string = "Lörem ipsüm dölör sit; ämet: cönsectetüer ädipiscing elit. Aliqüäm söllicitüdin fäücibüs mäüris ämet.";
+echo Horde_String::wordwrap($string, 31, "\n", false, 'utf-8', true) . "\n\n";
+$string = "Lörem ipsüm dölör sit; ämet:cönsectetüer ädipiscing elit. Aliqüäm söllicitüdin fäücibüs mäüris ämet.";
+echo Horde_String::wordwrap($string, 31, "\n", false, 'utf-8', true) . "\n\n";
+$string = "Lörem ipsüm dölör sit; ämet; cönsectetüer ädipiscing elit. Aliqüäm söllicitüdin fäücibüs mäüris ämet.";
+echo Horde_String::wordwrap($string, 31, "\n", false, 'utf-8', true) . "\n\n";
+$string = "Lörem ipsüm dölör sit; ämet;cönsectetüer ädipiscing elit. Aliqüäm söllicitüdin fäücibüs mäüris ämet.";
+echo Horde_String::wordwrap($string, 31, "\n", false, 'utf-8', true) . "\n\n";
+
+?>
+--EXPECT--
+Lörem ipsüm dölör sit ämet, cönsectetüer ädipiscing elit. Aliqüäm
+söllicitüdin fäücibüs mäüris ämet.
+
+Lörem ipsüm dölör sit ämet,
+ cönsectetüer ädipiscing elit.
+ Aliqüäm söllicitüdin fäücibüs
+ mäüris ämet.
+
+Lörem ipsüm dölör sit ämet, cönsectetüer ädipiscing elit.
+Aliqüäm söllicitüdin fäücibüs mäüris ämet.
+
+Lörem ipsüm dölör sit ämet, cönsectetüer ädipiscing elit. Aliqüäm
+söllicitüdin fäücibüs mäüris ämet.
+
+Lörem ipsüm dölör sit ämet, cönsectetüer ädipiscing elit. Aliqüäm
+söllicitüdin
+fäücibüs mäüris ämet.
+
+Löremipsümdölörsitämet,
+cönsectetüerädipiscingelit.
+
+Löremipsümdölör
+sitämet,
+cönsectetüerädi
+piscingelit.
+
+Lörem ipsüm dölör sit ämet,
+cönsectetüer ädipiscing
+
+Lörem ipsüm dölör sit ämet,
+cönsectetüer ädipiscing
+
+Löremipsümdölör
+sitämet,
+ cönsectetüeräd
+ipiscingelit.
+
+Lörem ipsüm dölör sit ämet,
+ cönsectetüer ädipiscing elit.
+ Aliqüäm söllicitüdin fäücibüs
+ mäüris ämet.
+
+Lörem ipsüm dölör sit;
+ ämet:
+ cönsectetüer ädipiscing elit.
+ Aliqüäm söllicitüdin fäücibüs
+ mäüris ämet.
+
+Lörem ipsüm dölör sit;
+ ämet:cönsectetüer ädipiscing
+ elit. Aliqüäm söllicitüdin
+ fäücibüs mäüris ämet.
+
+Lörem ipsüm dölör sit;
+ ämet;
+ cönsectetüer ädipiscing elit.
+ Aliqüäm söllicitüdin fäücibüs
+ mäüris ämet.
+
+Lörem ipsüm dölör sit;
+ ämet;cönsectetüer ädipiscing
+ elit. Aliqüäm söllicitüdin
+ fäücibüs mäüris ämet.