/** * Factory for a log object. Attempts to create a device specific file if * custom logging is requested. * * @param array $properties The property array. * * @return Horde_Log_Logger The logger object, correctly configured. */ public function create($properties = array()) { global $conf; $logger = false; if ($conf['activesync']['logging']['type'] == 'onefile') { if (!empty($properties['DeviceId'])) { $device_id = $properties['DeviceId']; $format = "%timestamp% {$device_id} %levelName%: %message%" . PHP_EOL; $formatter = new Horde_Log_Formatter_Simple(array('format' => $format)); $stream = fopen($conf['activesync']['logging']['path'], 'a'); if ($stream) { $logger = new Horde_Log_Logger(new Horde_Log_Handler_Stream($stream, false, $formatter)); } } } elseif ($conf['activesync']['logging']['type'] == 'perdevice') { if (!empty($properties['DeviceId'])) { $stream = fopen($conf['activesync']['logging']['path'] . '/' . Horde_String::upper($properties['DeviceId']) . '.txt', 'a'); if ($stream) { $logger = new Horde_Log_Logger(new Horde_Log_Handler_Stream($stream)); } } } if (!$logger) { $logger = new Horde_Log_Logger(new Horde_Log_Handler_Null()); } return $logger; }
/** * Attempt to do LMTP authentication. * * @param string The userid to authenticate as. * @param string The password to authenticate with. * @param string The requested authentication method. If none is * specified, the best supported method will be used. * * @return mixed Returns a PEAR_Error with an error message on any * kind of failure, or true on success. * @access public */ function auth($uid, $pwd, $method = '') { if (!isset($this->_esmtp['STARTTLS'])) { return PEAR::raiseError('LMTP server does not support authentication'); } if (PEAR::isError($result = $this->_put('STARTTLS'))) { return $result; } if (PEAR::isError($result = $this->_parseResponse(220))) { return $result; } if (PEAR::isError($result = $this->_socket->enableCrypto(true, STREAM_CRYPTO_METHOD_TLS_CLIENT))) { return $result; } elseif ($result !== true) { return PEAR::raiseError('STARTTLS failed'); } /* Send LHLO again to recieve the AUTH string from the LMTP server. */ $this->_negotiate(); if (empty($this->_esmtp['AUTH'])) { return PEAR::raiseError('LMTP server does not support authentication'); } /* * If no method has been specified, get the name of the best supported * method advertised by the LMTP server. */ if (empty($method) || $method === true) { if (PEAR::isError($method = $this->_getBestAuthMethod())) { /* Return the PEAR_Error object from _getBestAuthMethod(). */ return $method; } } else { $method = Horde_String::upper($method); } switch ($method) { case 'DIGEST-MD5': $result = $this->_authDigest_MD5($uid, $pwd); break; case 'CRAM-MD5': $result = $this->_authCRAM_MD5($uid, $pwd); break; case 'LOGIN': $result = $this->_authLogin($uid, $pwd); break; case 'PLAIN': $result = $this->_authPlain($uid, $pwd); break; default: $result = new PEAR_Error("{$method} is not a supported authentication method"); break; } /* If an error was encountered, return the PEAR_Error object. */ if (PEAR::isError($result)) { return $result; } /* RFC-2554 requires us to re-negotiate ESMTP after an AUTH. */ if (PEAR::isError($error = $this->_negotiate())) { return $error; } return true; }
/** * Constructor. * * Global constants defined: * - [APPNAME]_TEMPLATES - (string) Location of template files. * * @param string $app Application identifier. */ public final function __construct($app) { $this->_app = $app; $appname = Horde_String::upper($app); if (!defined($appname . '_TEMPLATES')) { define($appname . '_TEMPLATES', $GLOBALS['registry']->get('templates', $app)); } $this->_bootstrap(); }
/** * */ protected function _setup() { parent::_setup(); $view = $this->getView(); $view->addTemplatePath(array($GLOBALS['fs_base'] . '/app/views/App', $GLOBALS['fs_base'] . '/app/views/App/apps/' . $this->_matchDict->app)); $view->appname = $this->_matchDict->app; $view->hasAuthors = file_exists($GLOBALS['fs_base'] . '/app/views/App/apps/' . $this->_matchDict->app . '/appauthors.html.php'); $view->hasDocs = file_exists($GLOBALS['fs_base'] . '/app/views/App/apps/' . $this->_matchDict->app . '/docs'); $view->hasScreenshots = file_exists($GLOBALS['fs_base'] . '/app/views/App/apps/' . $this->_matchDict->app . '/appscreenshots.html.php'); $view->hasRoadmap = file_exists($GLOBALS['fs_base'] . '/app/views/App/apps/' . $this->_matchDict->app . '/approadmap.html.php'); // @TODO: Look this up in some kind of config/lookup array. $view->appnameHuman = in_array($this->_matchDict->app, array('imp', 'mimp', 'dimp')) ? Horde_String::upper($this->_matchDict->app) : Horde_String::ucfirst($this->_matchDict->app); }
/** * Parses a keyword expression. * * @param string $column This is the SQL field name the resulting * expression should test against. * @param string $expr This is the keyword expression we want to parse. * * @return string The query expression. * @throws Horde_Db_Exception */ public static function parse($column, $expr) { /* First pass - scan the string for tokens. Bare words are tokens, or * the user can quote strings to have embedded spaces, keywords, or * parentheses. Parentheses can be used for grouping boolean * operators, and the boolean operators AND, OR, and NOT are all * recognized. * * The tokens are returned in the $tokens array -- an array of strings. * Each string in the array starts with either a `!' or a `='. `=' is * a bare word or quoted string we are searching for, and `!' indicates * a boolean operator or parenthesis. A token that starts with a '.' * indicates a PostgreSQL word boundary search. */ $tokens = array(); while (!empty($expr)) { $expr = preg_replace('/^\\s+/', '', $expr); if (empty($expr)) { break; } if (substr($expr, 0, 1) == '(') { $expr = substr($expr, 1); $token = '!('; } elseif (substr($expr, 0, 1) == ')') { $expr = substr($expr, 1); $token = '!)'; } elseif (substr($expr, 0, 1) == ',') { $expr = substr($expr, 1); $token = '!OR'; } elseif (preg_match('/^(AND|OR|NOT)([^a-z].*)?$/i', $expr, $matches)) { $token = '!' . Horde_String::upper($matches[1]); $expr = substr($expr, strlen($matches[1])); } elseif (preg_match('/^"(([^"]|\\[0-7]+|\\[Xx][0-9a-fA-F]+|\\[^Xx0-7])*)"/', $expr, $matches)) { $token = '=' . stripcslashes($matches[1]); $expr = substr($expr, strlen($matches[0])); } elseif (preg_match('/^[^\\s\\(\\),]+/', $expr, $matches)) { $token = '=' . $matches[0]; $expr = substr($expr, strlen($token) - 1); } else { throw new Horde_Db_Exception('Syntax error in search terms'); } if ($token == '!AND') { /* !AND is implied by concatenation. */ continue; } $tokens[] = $token; } /* Call the expression parser. */ return self::_parseKeywords1($column, $tokens); }
/** */ protected function _changePassword($user, $oldpass, $newpass) { parent::_changePassword($user, $oldpass, $newpass); // Get existing user information. $entry = $this->_ldap->getEntry($this->_userdn); // Return if the user is not a Samba user. if (!in_array($this->_params['smb_objectclass'], $entry->getValue('objectClass', 'all'))) { return; } // Crypt_CHAP is not PSR-0 compatible. require_once 'Crypt/CHAP.php'; $hash = new Crypt_CHAP_MSv2(); $hash->password = $newpass; $lmpasswd = Horde_String::upper(bin2hex($hash->lmPasswordHash())); $ntpasswd = Horde_String::upper(bin2hex($hash->ntPasswordHash())); $settime = time(); if (!is_null($this->_params['pw_expire_time'])) { // 24 hours/day * 60 min/hour * 60 secs/min = 86400 seconds/day $expiretime = $settime + $this->_params['pw_expire_time'] * 86400; } else { // This is NT's version of infinity time: // http://lists.samba.org/archive/samba/2004-January/078175.html $expiretime = 2147483647; } // All changes must succeed or fail together. Attributes with // null name are not updated. $changes = array(); if (!is_null($this->_params['lm_attribute'])) { $changes[$this->_params['lm_attribute']] = $lmpasswd; } if (!is_null($this->_params['nt_attribute'])) { $changes[$this->_params['nt_attribute']] = $ntpasswd; } if (!is_null($this->_params['pw_set_attribute'])) { $changes[$this->_params['pw_set_attribute']] = $settime; } if (!is_null($this->_params['pw_expire_attribute'])) { $changes[$this->_params['pw_expire_attribute']] = $expiretime; } if (count($changes) > 0) { try { $entry->replace($changes, true); $entry->update(); } catch (Horde_Ldap_Exception $e) { throw new Passwd_Exception($e); } } }
/** * Set a capability as enabled/disabled. * * @param array $capability A capability (+ parameter). * @param boolean $enable If true, enables the capability. */ public function enable($capability, $enable = true) { $capability = Horde_String::upper($capability); $enabled = $this->isEnabled($capability); if ($enable && !$enabled) { switch ($capability) { case 'QRESYNC': /* RFC 7162 [3.2.3] - Enabling QRESYNC also implies enabling * of CONDSTORE. */ $this->enable('CONDSTORE'); break; } $this->_enabled[] = $capability; $this->notify(); } elseif (!$enable && $enabled) { $this->_enabled = array_diff($this->_enabled, array($capability)); $this->notify(); } }
/** * Factory for a log object. Attempts to create a device specific file if * custom logging is requested. * * @param array $properties The property array. * * @return Horde_Log_Logger The logger object, correctly configured. */ public function create($properties = array()) { global $conf; $logger = false; switch ($conf['activesync']['logging']['type']) { case 'onefile': if (!empty($properties['DeviceId'])) { $device_id = Horde_String::upper($properties['DeviceId']); $format = "%timestamp% {$device_id} %levelName%: %message%" . PHP_EOL; $formatter = new Horde_Log_Formatter_Simple(array('format' => $format)); $stream = fopen($conf['activesync']['logging']['path'], 'a'); if ($stream) { $logger = new Horde_Log_Logger(new Horde_Log_Handler_Stream($stream, false, $formatter)); } } break; case 'perdevice': if (!empty($properties['DeviceId'])) { $stream = fopen($conf['activesync']['logging']['path'] . '/' . Horde_String::upper($properties['DeviceId']) . '.txt', 'a'); if ($stream) { $logger = new Horde_Log_Logger(new Horde_Log_Handler_Stream($stream)); } } break; case 'perrequest': if (!empty($properties['DeviceId'])) { $dir = sprintf('%s/%s', $conf['activesync']['logging']['path'], Horde_String::upper($properties['DeviceId'])); if (!is_dir($dir)) { mkdir($dir, 0755, true); } $path = sprintf('%s/%s-%s-%s.txt', $dir, time(), getmypid(), !empty($properties['Cmd']) ? $properties['Cmd'] : 'UnknownCmd'); $stream = fopen($path, 'a'); if ($stream) { $logger = new Horde_Log_Logger(new Horde_Log_Handler_Stream($stream)); } } } if (!$logger) { $logger = new Horde_Log_Logger(new Horde_Log_Handler_Null()); } return $logger; }
public function dayMatches($ts) { if (!empty($this->day['value']) && $this->day['value'] == '*') { return true; } $currentdaynum = '-' . date('j', $ts) . '-'; $currentdaytxt = Horde_String::upper(date('D')); foreach ($this->day as $day) { if (@strpos($day['not'], $currentdaytxt) === false) { $v1 = @strpos($day['value'], $currentdaynum) !== false; $v2 = @strpos($day['and'], $currentdaytxt) !== false; if (!empty($day['and']) && ($v1 && $v2)) { return true; } elseif (empty($day['and']) && $v1) { return true; } } } return false; }
/** * Initialize a HordeMap. * * @param array $params */ public static function init(array $params = array()) { global $browser, $conf, $language, $page_output, $registry; // Language specific file needed? $language = str_replace('_', '-', $language); if (!file_exists($registry->get('jsfs', 'horde') . '/map/lang/' . $language . '.js')) { $language = 'en-US'; } $params = array_merge(array('conf' => array('language' => $language, 'markerImage' => strval(Horde_Themes::img('map/marker.png')), 'markerBackground' => strval(Horde_Themes::img('map/marker-shadow.png')), 'useMarkerLayer' => true), 'driver' => 'Horde', 'geocoder' => $conf['maps']['geocoder'], 'jsuri' => $registry->get('jsuri', 'horde') . '/map/', 'providers' => $conf['maps']['providers'], 'ssl' => $browser->usingSSLConnection()), $params); foreach ($params['providers'] as $layer) { switch ($layer) { case 'Google': $params['conf']['apikeys']['google'] = $conf['api']['googlemaps']; break; case 'Cloudmade': $params['conf']['apikeys']['cloudmade'] = $conf['api']['cloudmade']; break; case 'Mytopo': /* Mytopo requires a hash of the *client* IP address and the * key. Note that this also causes Mytopo to break if the * client's IP address presented as an internal address. */ $params['conf']['apikeys']['mytopo'] = array('id' => $conf['api']['mytopo_partnerID'], 'hash' => Horde_String::upper(md5($conf['api']['mytopo'] . $browser->getIpAddress()))); break; } } if (!empty($params['geocoder'])) { switch ($params['geocoder']) { case 'Google': $params['conf']['apikeys']['google'] = $conf['api']['googlemaps']; break; case 'Cloudmade': $params['conf']['apikeys']['cloudmade'] = $conf['api']['cloudmade']; break; } } $page_output->addScriptFile('map/map.js', 'horde'); $page_output->addInlineScript(array('HordeMap.initialize(' . Horde_Serialize::serialize($params, HORDE_SERIALIZE::JSON) . ');')); }
/** * Returns the VFS instance. * * @param string $backend The backend to return. * * @return Horde_Vfs The VFS object. */ public function create($backend) { if (empty($this->_instances[$backend])) { $be_config = Gollem_Auth::getBackend($backend); $params = $be_config['params']; switch (Horde_String::lower($be_config['driver'])) { case 'sql': case 'sqlfile': case 'musql': $db_params = $params; unset($db_params['table']); $params['db'] = $this->_injector->getInstance('Horde_Core_Factory_Db')->create('gollem', $db_params); $params['user'] = $GLOBALS['registry']->getAuth(); break; } $vfs = Horde_Vfs::factory($be_config['driver'], $params); if (!empty($be_config['quota'])) { $vfs->setQuotaRoot($be_config['root'] == '/' ? '' : $be_config['root']); if (isset($be_config['quota_val'])) { $vfs->setQuota($be_config['quota_val'], $be_config['quota_metric']); } else { $quota_metric = array('B' => Horde_Vfs::QUOTA_METRIC_BYTE, 'KB' => Horde_Vfs::QUOTA_METRIC_KB, 'MB' => Horde_Vfs::QUOTA_METRIC_MB, 'GB' => Horde_Vfs::QUOTA_METRIC_GB); $quota_str = explode(' ', $be_config['quota'], 2); if (is_numeric($quota_str[0])) { $metric = trim(Horde_String::upper($quota_str[1])); if (!isset($quota_metric[$metric])) { $metric = 'B'; } $vfs->setQuota($quota_str[0], $quota_metric[$metric]); } } } $this->_instances[$backend] = $vfs; } return $this->_instances[$backend]; }
/** * Return a comma-separated list of option strings & metavariables. */ public function formatOptionStrings($option) { if ($option->takesValue()) { $metavar = $option->metavar ? $option->metavar : Horde_String::upper($option->dest); $short_opts = array(); foreach ($option->shortOpts as $sopt) { $short_opts[] = sprintf($this->_short_opt_fmt, $sopt, $metavar); } $long_opts = array(); foreach ($option->longOpts as $lopt) { $long_opts[] = sprintf($this->_long_opt_fmt, $lopt, $metavar); } } else { $short_opts = $option->shortOpts; $long_opts = $option->longOpts; } if ($this->short_first) { $opts = array_merge($short_opts, $long_opts); } else { $opts = array_merge($long_opts, $short_opts); } return implode(', ', $opts); }
/** * Performs the actual copying/modifying of the files. * */ function transform($outdir) { global $files, $rawfiles, $info, $config; $pk = field_get_primary_key(); // search/replace arrays for default replacment of vocabulary: $search = array('zitem_id', 'ZOMBIE', 'zombie', 'Zombie', 'zitems', 'Zitems', 'zitem', 'Zitem'); $replace = array($pk['name'], Horde_String::upper($config['app']), Horde_String::lower($config['app']), Horde_String::ucfirst($config['app']), Horde_String::lower($config['set']), Horde_String::ucfirst($config['set']), Horde_String::lower($config['item']), Horde_String::ucfirst($config['item'])); foreach ($files as $file) { $infile = ZOMBIE_BASE . '/' . $file; // outfile may be renamed (zombie.php ->appname.php) $outfile = $outdir . '/' . str_replace($search, $replace, $file); mkdir_p(dirname($outfile)); $c = file_get_contents($infile); // deduct handler function name from the file name: $handler = str_replace('.php', '', trim($file)); $handler = str_replace('.inc', '', $handler); $handler = str_replace('/', '_', $handler); $handler = 't_' . $handler; // if handler is there, apply it: if (function_exists($handler)) { print "handler: {$file}\n"; $c = $handler($c); } else { print "copy : {$file}\n"; } //finally do default replacments and write file $c = str_replace($search, $replace, $c); $fh = fopen($outfile, "wb"); if ($fh) { fwrite($fh, $c); fclose($fh); } } // all the tricky stuff is done, just do raw copy of graphics: foreach ($rawfiles as $file) { $infile = "../{$file}"; // outfile is in outdir and maybe renamed (zombie.php ->appname.php) $outfile = $outdir . '/' . str_replace($search, $replace, $file); mkdir_p(dirname($outfile)); echo "rawcopy: {$file}\n"; copy($infile, $outfile); } }
/** * Adds rules from this ruleset to a VTIMEZONE component. * * @param Horde_Icalendar_Vtimezone $tz A VTIMEZONE component. * @param string $tzid The timezone ID of the component. * @param string $name A timezone name abbreviation. * May contain a placeholder that is * replaced the Rules' "Letter(s)" * entry. * @param array $startOffset An offset hash describing the * base offset of a timezone. * @param Horde_Date $start Start of the period to add rules * for. * @param Horde_Date $end End of the period to add rules * for. */ public function addRules(Horde_Icalendar_Vtimezone $tz, $tzid, $name, $startOffset, Horde_Date $start, Horde_Date $end = null) { $offset = $startOffset; foreach ($this->_rules as $rule) { $year = $rule[3]; if ($year[0] == 'o') { // TO is "only" $rule[3] = $rule[2]; } if ($rule[3][0] != 'm' && $rule[3] < $start->year) { // TO is not maximum and is before the searched period continue; } if ($end && $rule[2][0] != 'm' && $rule[2] > $end->year) { // FROM is not "minimum" and is after the searched period break; } if ($rule[2][0] != 'm' && $rule[2] < $start->year) { $rule[2] = $start->year; } if ($rule[8] == 0) { $component = new Horde_Icalendar_Standard(); $component->setAttribute('TZOFFSETFROM', $offset); $component->setAttribute('TZOFFSETTO', $startOffset); $offset = $startOffset; } else { $component = new Horde_Icalendar_Daylight(); $component->setAttribute('TZOFFSETFROM', $offset); $offset = $this->_getOffset($startOffset, $rule[8]); $component->setAttribute('TZOFFSETTO', $offset); } $month = Horde_Timezone::getMonth($rule[5]); // Retrieve time of rule start. preg_match('/(\\d+)(?::(\\d+))?(?::(\\d+))?(w|s|u)?/', $rule[7], $match); if (!isset($match[2])) { $match[2] = 0; } if ($rule[2] == $rule[3] && preg_match('/^\\d+$/', $rule[6])) { // Rule lasts only for a single year and starts on a specific // date. $rdate = new Horde_Date(array('year' => $rule[2], 'month' => Horde_Timezone::getMonth($rule[5]), 'mday' => $rule[6], 'hour' => $match[1], 'min' => $match[2], 'sec' => 0)); $component->setAttribute('DTSTART', $rdate); } elseif (substr($rule[6], 0, 4) == 'last') { // Rule starts on the last of a certain weekday of the month. $weekday = $this->_weekdays[substr($rule[6], 4, 3)]; $last = new Horde_Date(array('year' => $rule[2], 'month' => $month, 'mday' => Horde_Date_Utils::daysInMonth($month, $rule[2]), 'hour' => $match[1], 'min' => $match[2], 'sec' => 0)); while ($last->dayOfWeek() != $weekday) { $last->mday--; } $component->setAttribute('DTSTART', $last); if ($rule[3][0] == 'm') { $until = ''; } else { $last = new Horde_Date(array('year' => $rule[3], 'month' => $month, 'mday' => Horde_Date_Utils::daysInMonth($month, $rule[2]), 'hour' => $match[1], 'min' => $match[2], 'sec' => 0), $tzid); while ($last->dayOfWeek() != $weekday) { $last->mday--; } $last->setTimezone('UTC'); $until = ';UNTIL=' . $last->format('Ymd\\THIs') . 'Z'; } $component->setAttribute('RRULE', 'FREQ=YEARLY;BYDAY=-1' . Horde_String::upper(substr($rule[6], 4, 2)) . ';BYMONTH=' . $month . $until); } elseif (strpos($rule[6], '>=')) { // Rule starts on a certain weekday after a certain day of // month. list($weekday, $day) = explode('>=', $rule[6]); $weekdayInt = $this->_weekdays[substr($weekday, 0, 3)]; $first = new Horde_Date(array('year' => $rule[2], 'month' => $month, 'mday' => $day, 'hour' => $match[1], 'min' => $match[2], 'sec' => 0)); while ($first->dayOfWeek() != $weekdayInt) { $first->mday++; } $component->setAttribute('DTSTART', $first); if ($rule[3][0] == 'm') { $until = ''; } else { $last = new Horde_Date(array('year' => $rule[3], 'month' => $month, 'mday' => $day, 'hour' => $match[1], 'min' => $match[2], 'sec' => 0), $tzid); while ($last->dayOfWeek() != $weekday) { $last->mday++; } $last->setTimezone('UTC'); $until = ';UNTIL=' . $last->format('Ymd\\THIs') . 'Z'; } for ($days = array(), $i = $day, $lastDay = min(Horde_Date_Utils::daysInMonth($month, $rule[2]), $i + 6); $day > 1 && $i <= $lastDay; $i++) { $days[] = $i; } $component->setAttribute('RRULE', 'FREQ=YEARLY;BYMONTH=' . $month . ($days ? ';BYMONTHDAY=' . implode(',', $days) : '') . ';BYDAY=1' . Horde_String::upper(substr($weekday, 0, 2)) . $until); } elseif (strpos($rule[6], '<=')) { // Rule starts on a certain weekday before a certain day of // month. list($weekday, $day) = explode('>=', $rule[6]); $weekdayInt = $this->_weekdays[substr($weekday, 0, 3)]; $last = new Horde_Date(array('year' => $rule[2], 'month' => $month, 'mday' => $day, 'hour' => $match[1], 'min' => $match[2], 'sec' => 0)); while ($last->dayOfWeek() != $weekdayInt) { $last->mday--; } $component->setAttribute('DTSTART', $last); if ($rule[3][0] == 'm') { $until = ''; } else { $last = new Horde_Date(array('year' => $rule[3], 'month' => $month, 'mday' => $day, 'hour' => $match[1], 'min' => $match[2], 'sec' => 0), $tzid); while ($last->dayOfWeek() != $weekday) { $last->mday--; } $last->setTimezone('UTC'); $until = ';UNTIL=' . $last->format('Ymd\\THIs') . 'Z'; } for ($days = array(), $i = 1; $i <= $day; $i++) { $days[] = $i; } $component->setAttribute('RRULE', 'FREQ=YEARLY;BYMONTH=' . $month . ';BYMONTHDAY=' . implode(',', $days) . ';BYDAY=-1' . Horde_String::upper(substr($weekday, 0, 2)) . $until); } $component->setAttribute('TZNAME', sprintf($name, $rule[9])); $tz->addComponent($component); } }
echo _("Today"); } elseif ($which == 1) { echo _("Tomorrow"); } else { echo strftime('%A', mktime(0, 0, 0, date('m'), date('d') + $futureDays, date('Y'))); } ?> </strong><br /><?php echo strftime('%b %d', mktime(0, 0, 0, date('m'), date('d') + $futureDays, date('Y'))); ?> </td> <td><span style="color:red"><?php echo $day->high . '°' . Horde_String::upper($this->units['temp']); ?> </span>/<span style="color:blue"><?php echo $day->low . '°' . Horde_String::upper($this->units['temp']); ?> </span></td> <td><?php echo Horde_Themes_Image::tag('weather/32x32/' . $day->icon); ?> <br /><?php echo $day->conditions; ?> </td> <?php if (isset($this->params['detailedForecast'])) { ?> <?php if (in_array(Horde_Service_Weather::FORECAST_FIELD_PRECIPITATION, $this->forecast->fields)) { ?>
function _renderVarDisplay_address($form, $var, $vars) { global $registry; $address = $var->getValue($vars); if (preg_match('/((?:A[BL]|B[ABDHLNRST]?|C[ABFHMORTVW]|D[ADEGHLNTY]|E[CHNX]?|F[KY]|G[LUY]?|H[ADGPRSUX]|I[GMPV]|JE|K[ATWY]|L[ADELNSU]?|M[EKL]?|N[EGNPRW]?|O[LX]|P[AEHLOR]|R[GHM]|S[AEGKLMNOPRSTWY]?|T[ADFNQRSW]|UB|W[ACDFNRSV]?|YO|ZE)\\d(?:\\d|[A-Z])? \\d[A-Z]{2})/', $address, $postcode)) { /* UK postcode detected. */ /* Multimap.co.uk generated map */ $mapurl = 'http://www.multimap.com/map/browse.cgi?pc=' . urlencode($postcode[1]); $desc = Horde_Model_Translation::t("Multimap UK map"); $icon = 'map.png'; } elseif (preg_match('/ACT|NSW|NT|QLD|SA|TAS|VIC|WA/', $address)) { /* Australian state detected. */ /* Whereis.com.au generated map */ $mapurl = 'http://www.whereis.com.au/whereis/mapping/geocodeAddress.do?'; $desc = Horde_Model_Translation::t("Whereis Australia map"); $icon = 'map.png'; /* Split out the address, line-by-line. */ $addressLines = explode("\n", $address); for ($i = 0; $i < count($addressLines); $i++) { /* See if it's the street number & name. */ if (preg_match('/(\\d+\\s*\\/\\s*)?(\\d+|\\d+[a-zA-Z])\\s+([a-zA-Z ]*)/', $addressLines[$i], $lineParts)) { $mapurl .= '&streetNumber=' . urlencode($lineParts[2]); $mapurl .= '&streetName=' . urlencode($lineParts[3]); } /* Look for "Suburb, State". */ if (preg_match('/([a-zA-Z ]*),?\\s+' . $aus_state_regexp . '/', $addressLines[$i], $lineParts)) { $mapurl .= '&suburb=' . urlencode($lineParts[1]); } /* Look for "State <4 digit postcode>". */ if (preg_match('/(' . $aus_state_regexp . ')\\s+(\\d{4})/', $addressLines[$i], $lineParts)) { $mapurl .= '&state=' . urlencode($lineParts[1]); } } } elseif (preg_match('/(.*)\\n(.*)\\s*,\\s*(\\w+)\\.?\\s+(\\d+|[a-zA-Z]\\d[a-zA-Z]\\s?\\d[a-zA-Z]\\d)/', $address, $addressParts)) { /* American/Canadian address style. */ /* Mapquest generated map */ $mapurl = 'http://www.mapquest.com/maps/map.adp?size=big&zoom=7'; $desc = Horde_Model_Translation::t("MapQuest map"); $icon = 'map.png'; $country = null; if (!empty($addressParts[4]) && preg_match('|[a-zA-Z]\\d[a-zA-Z]\\s?\\d[a-zA-Z]\\d|', $addressParts[4])) { $country = 'CA'; } if (!empty($addressParts[1])) { $mapurl .= '&address=' . urlencode($addressParts[1]); } if (!empty($addressParts[2])) { $mapurl .= '&city=' . urlencode($addressParts[2]); } if (!empty($addressParts[3])) { $mapurl .= '&state=' . urlencode($addressParts[3]); } if (!empty($addressParts[4])) { if ($country == 'CA') { $mapurl .= '&country=CA'; } $mapurl .= '&zipcode=' . urlencode($addressParts[4]); } /* Yahoo! generated map. */ $mapurl2 = 'http://us.rd.yahoo.com/maps/home/submit_a/*-http://maps.yahoo.com/maps?srchtype=a&getmap=Get+Map&'; $desc2 = Horde_Model_Translation::t("Yahoo! map"); $icon2 = 'map.png'; if (!empty($addressParts[1])) { $mapurl2 .= '&addr=' . urlencode($addressParts[1]); } /* Give precedence to zipcode over city/state */ if (empty($addressParts[4]) && !empty($addressParts[2]) && !empty($addressParts[3])) { $mapurl2 .= '&csz=' . urlencode($addressParts[2] . ' ' . $addressParts[3]); } if (!empty($addressParts[4])) { if (preg_match('|([a-zA-Z]\\d[a-zA-Z])\\s?(\\d[a-zA-Z]\\d)|', $addressParts[4], $pcParts)) { $mapurl2 .= '&country=ca'; /* make sure the postal-code has a space */ $addressParts[4] = $pcParts[1] . ' ' . $pcParts[2]; } $mapurl2 .= '&csz=' . urlencode($addressParts[4]); } /* Google generated map. */ $mapurl3 = 'http://maps.google.com/maps?q=' . urlencode($addressParts[0]) . '&hl=en'; $desc3 = Horde_Model_Translation::t("Google Maps"); $icon3 = 'map.png'; } elseif (preg_match('/(.*?)\\r?\\n([A-Z]{1,3})-(\\d{5})\\s+(.*)/i', $address, $addressParts)) { /* European address style. */ include 'Horde/Nls/Carsigns.php'; $country = array_search(Horde_String::upper($addressParts[2]), $carsigns); /* Map24 generated map. */ if (in_array($country, array('al', 'ad', 'am', 'az', 'be', 'ba', 'bg', 'de', 'dk', 'ee', 'fo', 'fi', 'fr', 'ge', 'gr', 'gb', 'ie', 'is', 'it', 'hr', 'lv', 'li', 'lt', 'lu', 'mt', 'mk', 'md', 'mc', 'nl', 'no', 'pl', 'pt', 'ro', 'ru', 'se', 'ch', 'cs', 'sk', 'si', 'es', 'cz', 'tr', 'ua', 'hu', 'by', 'cy', 'at'))) { if (in_array($country, array('at', 'be', 'ch', 'de', 'dk', 'es', 'fi', 'fr', 'it', 'nl', 'no', 'se'))) { $mirror = $country; } else { $mirror = 'uk'; } $mapurl = 'http://www.' . $mirror . '.map24.com/source/address/v2.0.0/cnt_nav_maplet.php?cid=validateaddr&country=' . $country; $desc = Horde_Model_Translation::t("Map24 map"); $icon = 'map_eu.png'; if (!empty($addressParts[1])) { $mapurl .= '&street=' . urlencode($addressParts[1]); } if (!empty($addressParts[3])) { $mapurl .= '&zip=' . urlencode($addressParts[3]); } if (!empty($addressParts[4])) { $mapurl .= '&city=' . urlencode($addressParts[4]); } } /* Mapquest generated map. */ $mapurl2 = 'http://www.mapquest.com/maps/map.adp?country=' . Horde_String::upper($country); $desc2 = Horde_Model_Translation::t("MapQuest map"); $icon2 = 'map_eu.png'; if (!empty($addressParts[1])) { $mapurl2 .= '&address=' . urlencode($addressParts[1]); } if (!empty($addressParts[3])) { $mapurl2 .= '&zipcode=' . urlencode($addressParts[3]); } if (!empty($addressParts[4])) { $mapurl2 .= '&city=' . urlencode($addressParts[4]); } } $html = nl2br(htmlspecialchars($var->getValue($vars))); if (!empty($mapurl)) { $html .= ' ' . Horde::link(Horde::externalUrl($mapurl), $desc, null, '_blank') . Horde::img($icon, $desc) . '</a>'; } if (!empty($mapurl2)) { $html .= ' ' . Horde::link(Horde::externalUrl($mapurl2), $desc2, null, '_blank') . Horde::img($icon2, $desc2) . '</a>'; } if (!empty($mapurl3)) { $html .= ' ' . Horde::link(Horde::externalUrl($mapurl3), $desc3, null, '_blank') . Horde::img($icon3, $desc3) . '</a>'; } return $html; }
/** * Given a 2-letter country code, returns a country string. * * @param string $code The country code. * * @return string The country string. */ protected function _getName($code) { $code = Horde_String::upper($code); $geoip_codes = array('AP' => Horde_Nls_Translation::t("Asia/Pacific Region"), 'EU' => Horde_Nls_Translation::t("Europe"), 'A1' => Horde_Nls_Translation::t("Anonymous Proxy"), 'A2' => Horde_Nls_Translation::t("Satellite Provider"), 'O1' => Horde_Nls_Translation::t("Other")); return isset($geoip_codes[$code]) ? $geoip_codes[$code] : strval(Horde_Nls::getCountryISO($code)); }
/** * Maps an iCalendar attendee response string to the corresponding * Nag value. * * @param string $response The attendee response. * * @return string The Nag response value. */ public static function responseFromICal($response) { switch (Horde_String::upper($response)) { case 'ACCEPTED': return self::RESPONSE_ACCEPTED; case 'DECLINED': return self::RESPONSE_DECLINED; case 'NEEDS-ACTION': default: return self::RESPONSE_NONE; } }
/** * Creates a task from a Horde_Icalendar_Vtodo object. * * @param Horde_Icalendar_Vtodo $vTodo The iCalendar data to update from. */ public function fromiCalendar(Horde_Icalendar_Vtodo $vTodo) { /* Owner is always current user. */ $this->owner = $GLOBALS['registry']->getAuth(); try { $name = $vTodo->getAttribute('SUMMARY'); if (!is_array($name)) { $this->name = $name; } } catch (Horde_Icalendar_Exception $e) { } // Not sure why we were mapping the ORGANIZER to the person the // task is assigned to? If anything, this needs to be mapped to // any ATTENDEE fields from the vTodo. // try { // $assignee = $vTodo->getAttribute('ORGANIZER'); // if (!is_array($assignee)) { $this->assignee = $assignee; } // } catch (Horde_Icalendar_Exception $e) {} try { $organizer = $vTodo->getAttribute('ORGANIZER'); if (!is_array($organizer)) { $this->organizer = $organizer; } } catch (Horde_Icalendar_Exception $e) { } // If an attendee matches our from_addr, add current user as assignee. try { $atnames = $vTodo->getAttribute('ATTENDEE'); if (!is_array($atnames)) { $atnames = array($atnames); } $identity = $GLOBALS['injector']->getInstance('Horde_Core_Factory_Identity')->create(); $all_addrs = $identity->getAll('from_addr'); foreach ($atnames as $index => $attendee) { if ($vTodo->getAttribute('VERSION') < 2) { $addr_ob = new Horde_Mail_Rfc822_Address($attendee); if (!$addr_ob->valid) { continue; } $attendee = $addr_ob->bare_address; $name = $addr_ob->personal; } else { $attendee = str_ireplace('mailto:', '', $attendee); $addr_ob = new Horde_Mail_Rfc822_Address($attendee); if (!$addr_ob->valid) { continue; } $attendee = $addr_ob->bare_address; $name = isset($atparms[$index]['CN']) ? $atparms[$index]['CN'] : null; } if (in_array($attendee, $all_addrs) !== false) { $this->assignee = $GLOBALS['conf']['assignees']['allow_external'] ? $attendee : $GLOBALS['registry']->getAuth(); $this->status = Nag::RESPONSE_ACCEPTED; break; } elseif ($GLOBALS['conf']['assignees']['allow_external']) { $this->assignee = $attendee; } } } catch (Horde_Icalendar_Exception $e) { } // Default to current user as organizer if (empty($this->organizer) && !empty($this->assignee)) { $this->organizer = $identity->getValue('from_addr'); } try { $uid = $vTodo->getAttribute('UID'); if (!is_array($uid)) { $this->uid = $uid; } } catch (Horde_Icalendar_Exception $e) { } try { $relations = $vTodo->getAttribute('RELATED-TO'); if (!is_array($relations)) { $relations = array($relations); } $params = $vTodo->getAttribute('RELATED-TO', true); foreach ($relations as $id => $relation) { if (empty($params[$id]['RELTYPE']) || Horde_String::upper($params[$id]['RELTYPE']) == 'PARENT') { try { $parent = $this->_storage->getByUID($relation, $this->tasklist); $this->parent_id = $parent->id; } catch (Horde_Exception_NotFound $e) { } break; } } } catch (Horde_Icalendar_Exception $e) { } try { $start = $vTodo->getAttribute('DTSTART'); if (!is_array($start)) { // Date-Time field $this->start = $start; } else { // Date field $this->start = mktime(0, 0, 0, (int) $start['month'], (int) $start['mday'], (int) $start['year']); } } catch (Horde_Icalendar_Exception $e) { } try { $due = $vTodo->getAttribute('DUE'); if (is_array($due)) { $this->due = mktime(0, 0, 0, (int) $due['month'], (int) $due['mday'], (int) $due['year']); } elseif (!empty($due)) { $this->due = $due; } } catch (Horde_Icalendar_Exception $e) { } // Recurrence. try { $rrule = $vTodo->getAttribute('RRULE'); if (!is_array($rrule)) { $this->recurrence = new Horde_Date_Recurrence($this->due); if (strpos($rrule, '=') !== false) { $this->recurrence->fromRRule20($rrule); } else { $this->recurrence->fromRRule10($rrule); } // Completions. EXDATE represents completed tasks, just add the // exception. $exdates = $vTodo->getAttributeValues('EXDATE'); if (is_array($exdates)) { foreach ($exdates as $exdate) { if (is_array($exdate)) { $this->recurrence->addCompletion((int) $exdate['year'], (int) $exdate['month'], (int) $exdate['mday']); } } } } } catch (Horde_Icalendar_Exception $e) { } // vCalendar 1.0 alarms try { $alarm = $vTodo->getAttribute('AALARM'); if (!is_array($alarm) && !empty($alarm) && !empty($this->due)) { $this->alarm = intval(($this->due - $alarm) / 60); if ($this->alarm === 0) { // We don't support alarms exactly at due date. $this->alarm = 1; } } } catch (Horde_Icalendar_Exception $e) { } // vCalendar 2.0 alarms foreach ($vTodo->getComponents() as $alarm) { if (!$alarm instanceof Horde_Icalendar_Valarm) { continue; } try { if ($alarm->getAttribute('ACTION') == 'NONE') { continue; } } catch (Horde_Icalendar_Exception $e) { } try { // @todo consider implementing different ACTION types. // $action = $alarm->getAttribute('ACTION'); $trigger = $alarm->getAttribute('TRIGGER'); $triggerParams = $alarm->getAttribute('TRIGGER', true); } catch (Horde_Icalendar_Exception $e) { continue; } if (!is_array($triggerParams)) { $triggerParams = array($triggerParams); } $haveTrigger = false; foreach ($triggerParams as $tp) { if (isset($tp['VALUE']) && $tp['VALUE'] == 'DATE-TIME') { if (isset($tp['RELATED']) && $tp['RELATED'] == 'END') { if ($this->due) { $this->alarm = intval(($this->due - $trigger) / 60); $haveTrigger = true; break; } } else { if ($this->start) { $this->alarm = intval(($this->start - $trigger) / 60); $haveTrigger = true; break; } } } elseif (isset($tp['RELATED']) && $tp['RELATED'] == 'END' && $this->due && $this->start) { $this->alarm = -intval($trigger / 60); $this->alarm -= $this->due - $this->start; $haveTrigger = true; break; } } if (!$haveTrigger) { $this->alarm = -intval($trigger / 60); } break; } // Alarm snoozing/dismissal if ($this->alarm) { try { // If X-MOZ-LASTACK is set, this task is either dismissed or // snoozed. $vTodo->getAttribute('X-MOZ-LASTACK'); try { // If X-MOZ-SNOOZE-TIME is set, this task is snoozed. $snooze = $vTodo->getAttribute('X-MOZ-SNOOZE-TIME'); $this->snooze = intval(($snooze - time()) / 60); } catch (Horde_Icalendar_Exception $e) { // If X-MOZ-SNOOZE-TIME is not set, this event is dismissed. $this->snooze = -1; } } catch (Horde_Icalendar_Exception $e) { } } try { $desc = $vTodo->getAttribute('DESCRIPTION'); if (!is_array($desc)) { $this->desc = $desc; } } catch (Horde_Icalendar_Exception $e) { } try { $priority = $vTodo->getAttribute('PRIORITY'); if (!is_array($priority)) { $this->priority = $priority; } } catch (Horde_Icalendar_Exception $e) { } try { $cat = $vTodo->getAttribute('CATEGORIES'); if (!is_array($cat)) { $this->tags = $cat; } } catch (Horde_Icalendar_Exception $e) { } try { $status = $vTodo->getAttribute('STATUS'); if (!is_array($status)) { $this->completed = !strcasecmp($status, 'COMPLETED'); } } catch (Horde_Icalendar_Exception $e) { } try { $class = $vTodo->getAttribute('CLASS'); if (!is_array($class)) { $class = Horde_String::upper($class); $this->private = $class == 'PRIVATE' || $class == 'CONFIDENTIAL'; } } catch (Horde_Icalendar_Exception $e) { } }
/** * Search for text in the header of a message. * * @param string $header The header field. * @param string $text The search text. * @param boolean $not If true, do a 'NOT' search of $text. * @param array $opts Additional options: * - fuzzy: (boolean) If true, perform a fuzzy search. The IMAP server * MUST support RFC 6203. */ public function headerText($header, $text, $not = false, array $opts = array()) { if (!isset($this->_search['header'])) { $this->_search['header'] = array(); } $this->_search['header'][] = array_filter(array('fuzzy' => !empty($opts['fuzzy']), 'header' => Horde_String::upper($header), 'text' => $text, 'not' => $not)); }
/** * Begin a new page. * * @param string $orientation Orientation code * @return void */ protected function _beginPage($orientation) { $this->_page++; // only assign page contents if it is new if (!isset($this->_pages[$this->_page])) { $this->_pages[$this->_page] = ''; } $this->_state = 2; $this->x = $this->_left_margin; $this->y = $this->_top_margin; $this->_last_height = 0; // Page orientation if (!$orientation) { $orientation = $this->_default_orientation; } else { $orientation = Horde_String::upper($orientation[0]); if ($orientation != $this->_default_orientation) { $this->_orientation_changes[$this->_page] = true; } } if ($orientation != $this->_current_orientation) { // Change orientation if ($orientation == 'P') { $this->wPt = $this->fwPt; $this->hPt = $this->fhPt; $this->w = $this->fw; $this->h = $this->fh; } else { $this->wPt = $this->fhPt; $this->hPt = $this->fwPt; $this->w = $this->fh; $this->h = $this->fw; } $this->_page_break_trigger = $this->h - $this->_break_margin; $this->_current_orientation = $orientation; } }
function parse($address) { $info = array(); $aus_state_regex = '(?:ACT|NSW|NT|QLD|SA|TAS|VIC|WA)'; if (preg_match('/(?s)(.*?)(?-s)\\r?\\n(?:(.*?)\\s+)?((?:A[BL]|B[ABDHLNRST]?|C[ABFHMORTVW]|D[ADEGHLNTY]|E[CHNX]?|F[KY]|G[LUY]?|H[ADGPRSUX]|I[GMPV]|JE|K[ATWY]|L[ADELNSU]?|M[EKL]?|N[EGNPRW]?|O[LX]|P[AEHLOR]|R[GHM]|S[AEGKLMNOPRSTWY]?|T[ADFNQRSW]|UB|W[ACDFNRSV]?|YO|ZE)\\d(?:\\d|[A-Z])? \\d[A-Z]{2})/', $address, $addressParts)) { /* UK postcode detected. */ $info = array('country' => 'uk', 'zip' => $addressParts[3]); if (!empty($addressParts[1])) { $info['street'] = $addressParts[1]; } if (!empty($addressParts[2])) { $info['city'] = $addressParts[2]; } } elseif (preg_match('/\\b' . $aus_state_regex . '\\b/', $address)) { /* Australian state detected. */ /* Split out the address, line-by-line. */ $addressLines = preg_split('/\\r?\\n/', $address); $info = array('country' => 'au'); for ($i = 0; $i < count($addressLines); $i++) { /* See if it's the street number & name. */ if (preg_match('/(\\d+\\s*\\/\\s*)?(\\d+|\\d+[a-zA-Z])\\s+([a-zA-Z ]*)/', $addressLines[$i], $lineParts)) { $info['street'] = $addressLines[$i]; $info['streetNumber'] = $lineParts[2]; $info['streetName'] = $lineParts[3]; } /* Look for "Suburb, State". */ if (preg_match('/([a-zA-Z ]*),?\\s+(' . $aus_state_regex . ')/', $addressLines[$i], $lineParts)) { $info['city'] = $lineParts[1]; $info['state'] = $lineParts[2]; } /* Look for "State <4 digit postcode>". */ if (preg_match('/(' . $aus_state_regex . ')\\s+(\\d{4})/', $addressLines[$i], $lineParts)) { $info['state'] = $lineParts[1]; $info['zip'] = $lineParts[2]; } } } elseif (preg_match('/(?s)(.*?)(?-s)\\r?\\n(.*)\\s*,\\s*(\\w+)\\.?\\s+(\\d+|[a-zA-Z]\\d[a-zA-Z]\\s?\\d[a-zA-Z]\\d)/', $address, $addressParts)) { /* American/Canadian address style. */ $info = array('country' => 'us'); if (!empty($addressParts[4]) && preg_match('|[a-zA-Z]\\d[a-zA-Z]\\s?\\d[a-zA-Z]\\d|', $addressParts[4])) { $info['country'] = 'ca'; } if (!empty($addressParts[1])) { $info['street'] = $addressParts[1]; } if (!empty($addressParts[2])) { $info['city'] = $addressParts[2]; } if (!empty($addressParts[3])) { $info['state'] = $addressParts[3]; } if (!empty($addressParts[4])) { $info['zip'] = $addressParts[4]; } } elseif (preg_match('/(?:(?s)(.*?)(?-s)(?:\\r?\\n|,\\s*))?(?:([A-Z]{1,3})-)?(\\d{4,5})\\s+(.*)(?:\\r?\\n(.*))?/i', $address, $addressParts)) { /* European address style. */ $info = array(); if (!empty($addressParts[1])) { $info['street'] = $addressParts[1]; } if (!empty($addressParts[2])) { include 'Horde/Nls/Carsigns.php'; $country = array_search(Horde_String::upper($addressParts[2]), $carsigns); if ($country) { $info['country'] = $country; } } if (!empty($addressParts[5])) { include 'Horde/Nls/Countries.php'; $country = array_search($addressParts[5], $countries); if ($country) { $info['country'] = Horde_String::lower($country); } elseif (!isset($info['street'])) { $info['street'] = trim($addressParts[5]); } else { $info['street'] .= "\n" . $addressParts[5]; } } if (!empty($addressParts[3])) { $info['zip'] = $addressParts[3]; } if (!empty($addressParts[4])) { $info['city'] = trim($addressParts[4]); } } return $info; }
/** * Uppercases the HTTP method */ protected function _getNormalizedHttpMethod() { return Horde_String::upper($this->_method); }
/** * Converts a DN into a canonical form. * * DN can either be a string or an array as returned by explodeDN(), * which is useful when constructing a DN. The DN array may have be * indexed (each array value is a OCL=VALUE pair) or associative (array key * is OCL and value is VALUE). * * It performs the following operations on the given DN: * - Removes the leading 'OID.' characters if the type is an OID instead of * a name. * - Escapes all RFC 2253 special characters (",", "+", """, "\", "<", ">", * ";", "#", "="), slashes ("/"), and any other character where the ASCII * code is < 32 as \hexpair. * - Converts all leading and trailing spaces in values to be \20. * - If an RDN contains multiple parts, the parts are re-ordered so that * the attribute type names are in alphabetical order. * * $options is a list of name/value pairs, valid options are: * * - casefold: Controls case folding of attribute type names. Attribute * values are not affected by this option. The default is to * uppercase. Valid values are: * - lower: Lowercase attribute type names. * - upper: Uppercase attribute type names. * - none: Do not change attribute type names. * - reverse: If true, the RDN sequence is reversed. * - separator: Separator to use between RDNs. Defaults to comma (','). * * The empty string "" is a valid DN, so be sure not to do a "$can_dn == * false" test, because an empty string evaluates to false. Use the "===" * operator instead. * * @param array|string $dn The DN. * @param array $options Options to use. * * @return boolean|string The canonical DN or false if the DN is not valid. */ public static function canonicalDN($dn, $options = array()) { if ($dn === '') { // Empty DN is valid. return $dn; } // Options check. $options['reverse'] = !empty($options['reverse']); if (!isset($options['casefold'])) { $options['casefold'] = 'upper'; } if (!isset($options['separator'])) { $options['separator'] = ','; } if (!is_array($dn)) { // It is not clear to me if the perl implementation splits by the // user defined separator or if it just uses this separator to // construct the new DN. $dn = preg_split('/(?<!\\\\)' . $options['separator'] . '/', $dn); // Clear wrong splitting (possibly we have split too much). $dn = self::_correctDNSplitting($dn, $options['separator']); } else { // Is array, check if the array is indexed or associative. $assoc = false; foreach ($dn as $dn_key => $dn_part) { if (!is_int($dn_key)) { $assoc = true; break; } } // Convert to indexed, if associative array detected. if ($assoc) { $newdn = array(); foreach ($dn as $dn_key => $dn_part) { if (is_array($dn_part)) { // We assume here that the RDN parts are also // associative. ksort($dn_part, SORT_STRING); // Copy array as-is, so we can resolve it later. $newdn[] = $dn_part; } else { $newdn[] = $dn_key . '=' . $dn_part; } } $dn =& $newdn; } } // Escaping and casefolding. foreach ($dn as $pos => $dnval) { if (is_array($dnval)) { // Subarray detected, this means most probably that we had a // multivalued DN part, which must be resolved. $dnval_new = ''; foreach ($dnval as $subkey => $subval) { // Build RDN part. if (!is_int($subkey)) { $subval = $subkey . '=' . $subval; } $subval_processed = self::canonicalDN($subval); if (false === $subval_processed) { return false; } $dnval_new .= $subval_processed . '+'; } // Store RDN part, strip last plus. $dn[$pos] = substr($dnval_new, 0, -1); } else { // Try to split multivalued RDNs into array. $rdns = self::splitRDNMultivalue($dnval); if (count($rdns) > 1) { // Multivalued RDN was detected. The RDN value is expected // to be correctly split by splitRDNMultivalue(). It's time // to sort the RDN and build the DN. $rdn_string = ''; // Sort RDN keys alphabetically. sort($rdns, SORT_STRING); foreach ($rdns as $rdn) { $subval_processed = self::canonicalDN($rdn); if (false === $subval_processed) { return false; } $rdn_string .= $subval_processed . '+'; } // Store RDN part, strip last plus. $dn[$pos] = substr($rdn_string, 0, -1); } else { // No multivalued RDN. Split at first unescaped "=". $dn_comp = self::splitAttributeString($rdns[0]); if (count($dn_comp) != 2) { throw new Horde_Ldap_Exception('Invalid RDN: ' . $rdns[0]); } // Trim left whitespaces because of "cn=foo, l=bar" syntax // (whitespace after comma). $ocl = ltrim($dn_comp[0]); $val = $dn_comp[1]; // Strip 'OID.', otherwise apply casefolding and escaping. if (substr(Horde_String::lower($ocl), 0, 4) == 'oid.') { $ocl = substr($ocl, 4); } else { if ($options['casefold'] == 'upper') { $ocl = Horde_String::upper($ocl); } if ($options['casefold'] == 'lower') { $ocl = Horde_String::lower($ocl); } $ocl = self::escapeDNValue(array($ocl)); $ocl = $ocl[0]; } // Escaping of DN value. // TODO: if the value is already correctly escaped, we get // double escaping. $val = self::escapeDNValue(array($val)); $val = str_replace('/', '\\/', $val[0]); $dn[$pos] = $ocl . '=' . $val; } } } if ($options['reverse']) { $dn = array_reverse($dn); } return implode($options['separator'], $dn); }
/** * Updates the properties of this event from a Horde_Icalendar_Vevent * object. * * @param Horde_Icalendar_Vevent $vEvent The iCalendar data to update * from. * @param boolean $parseAttendees Parse attendees too? * @since Kronolith 4.2 */ public function fromiCalendar($vEvent, $parseAttendees = false) { // Unique ID. try { $uid = $vEvent->getAttribute('UID'); if (!empty($uid)) { $this->uid = $uid; } } catch (Horde_Icalendar_Exception $e) { } // Sequence. try { $seq = $vEvent->getAttribute('SEQUENCE'); if (is_int($seq)) { $this->sequence = $seq; } } catch (Horde_Icalendar_Exception $e) { } // Title, tags and description. try { $title = $vEvent->getAttribute('SUMMARY'); if (!is_array($title)) { $this->title = $title; } } catch (Horde_Icalendar_Exception $e) { } // Tags try { $this->_tags = $vEvent->getAttributeValues('CATEGORIES'); } catch (Horde_Icalendar_Exception $e) { } // Description try { $desc = $vEvent->getAttribute('DESCRIPTION'); if (!is_array($desc)) { $this->description = $desc; } } catch (Horde_Icalendar_Exception $e) { } // Remote Url try { $url = $vEvent->getAttribute('URL'); if (!is_array($url)) { $this->url = $url; } } catch (Horde_Icalendar_Exception $e) { } // Location try { $location = $vEvent->getAttribute('LOCATION'); if (!is_array($location)) { $this->location = $location; } } catch (Horde_Icalendar_Exception $e) { } try { $geolocation = $vEvent->getAttribute('GEO'); $this->geoLocation = array('lat' => $geolocation['latitude'], 'lon' => $geolocation['longitude']); } catch (Horde_Icalendar_Exception $e) { } // Class try { $class = $vEvent->getAttribute('CLASS'); if (!is_array($class)) { $class = Horde_String::upper($class); $this->private = $class == 'PRIVATE' || $class == 'CONFIDENTIAL'; } } catch (Horde_Icalendar_Exception $e) { } // Status. try { $status = $vEvent->getAttribute('STATUS'); if (!is_array($status)) { $status = Horde_String::upper($status); if ($status == 'DECLINED') { $status = 'CANCELLED'; } if (defined('Kronolith::STATUS_' . $status)) { $this->status = constant('Kronolith::STATUS_' . $status); } } } catch (Horde_Icalendar_Exception $e) { } // Reset allday flag in case this has changed. Will be recalculated // next time isAllDay() is called. $this->allday = false; // Start and end date. $tzid = null; try { $start = $vEvent->getAttribute('DTSTART'); $startParams = $vEvent->getAttribute('DTSTART', true); // We don't support different timezones for different attributes, // so use the DTSTART timezone for the complete event. if (isset($startParams[0]['TZID'])) { // Horde_Date supports timezone aliases, so try that first. $tz = $startParams[0]['TZID']; try { // Check if the timezone name is supported by PHP natively. new DateTimeZone($tz); $this->timezone = $tzid = $tz; } catch (Exception $e) { } } if (!is_array($start)) { // Date-Time field $this->start = new Horde_Date($start, $tzid); } else { // Date field $this->start = new Horde_Date(array('year' => (int) $start['year'], 'month' => (int) $start['month'], 'mday' => (int) $start['mday']), $tzid); } } catch (Horde_Icalendar_Exception $e) { throw new Kronolith_Exception($e); } catch (Horde_Date_Exception $e) { throw new Kronolith_Exception($e); } try { $end = $vEvent->getAttribute('DTEND'); if (!is_array($end)) { // Date-Time field $this->end = new Horde_Date($end, $tzid); // All day events are transferred by many device as // DSTART: YYYYMMDDT000000 DTEND: YYYYMMDDT2359(59|00) // Convert accordingly if (is_object($this->start) && $this->start->hour == 0 && $this->start->min == 0 && $this->start->sec == 0 && $this->end->hour == 23 && $this->end->min == 59) { $this->end = new Horde_Date(array('year' => (int) $this->end->year, 'month' => (int) $this->end->month, 'mday' => (int) $this->end->mday + 1), $tzid); } } else { // Date field $this->end = new Horde_Date(array('year' => (int) $end['year'], 'month' => (int) $end['month'], 'mday' => (int) $end['mday']), $tzid); } } catch (Horde_Icalendar_Exception $e) { $end = null; } if (is_null($end)) { try { $duration = $vEvent->getAttribute('DURATION'); if (!is_array($duration)) { $this->end = new Horde_Date($this->start); $this->end->sec += $duration; $end = 1; } } catch (Horde_Icalendar_Exception $e) { } if (is_null($end)) { // End date equal to start date as per RFC 2445. $this->end = new Horde_Date($this->start); if (is_array($start)) { // Date field $this->end->mday++; } } } // vCalendar 1.0 alarms try { $alarm = $vEvent->getAttribute('AALARM'); if (!is_array($alarm) && intval($alarm)) { $this->alarm = intval(($this->start->timestamp() - $alarm) / 60); } } catch (Horde_Icalendar_Exception $e) { } // vCalendar 2.0 alarms foreach ($vEvent->getComponents() as $alarm) { if (!$alarm instanceof Horde_Icalendar_Valarm) { continue; } try { if ($alarm->getAttribute('ACTION') == 'NONE') { continue; } } catch (Horde_Icalendar_Exception $e) { } try { // @todo consider implementing different ACTION types. // $action = $alarm->getAttribute('ACTION'); $trigger = $alarm->getAttribute('TRIGGER'); $triggerParams = $alarm->getAttribute('TRIGGER', true); } catch (Horde_Icalendar_Exception $e) { continue; } if (!is_array($triggerParams)) { $triggerParams = array($triggerParams); } $haveTrigger = false; foreach ($triggerParams as $tp) { if (isset($tp['VALUE']) && $tp['VALUE'] == 'DATE-TIME') { if (isset($tp['RELATED']) && $tp['RELATED'] == 'END') { $this->alarm = intval(($this->end->timestamp() - $trigger) / 60); } else { $this->alarm = intval(($this->start->timestamp() - $trigger) / 60); } $haveTrigger = true; break; } elseif (isset($tp['RELATED']) && $tp['RELATED'] == 'END') { $this->alarm = -intval($trigger / 60); $this->alarm -= $this->durMin; $haveTrigger = true; break; } } if (!$haveTrigger) { $this->alarm = -intval($trigger / 60); } break; } // Alarm snoozing/dismissal if ($this->alarm) { try { // If X-MOZ-LASTACK is set, this event is either dismissed or // snoozed. $vEvent->getAttribute('X-MOZ-LASTACK'); try { // If X-MOZ-SNOOZE-TIME is set, this event is snoozed. $snooze = $vEvent->getAttribute('X-MOZ-SNOOZE-TIME'); $this->_snooze = intval(($snooze - time()) / 60); } catch (Horde_Icalendar_Exception $e) { // If X-MOZ-SNOOZE-TIME is not set, this event is dismissed. $this->_snooze = -1; } } catch (Horde_Icalendar_Exception $e) { } } // Attendance. // Importing attendance may result in confusion: editing an imported // copy of an event can cause invitation updates to be sent from // people other than the original organizer. So we don't import by // default. However to allow updates by synchronization, this behavior // can be overriden. // X-ATTENDEE is there for historical reasons. @todo remove in // Kronolith 5. $attendee = null; if ($parseAttendees) { try { $attendee = $vEvent->getAttribute('ATTENDEE'); $params = $vEvent->getAttribute('ATTENDEE', true); } catch (Horde_Icalendar_Exception $e) { try { $attendee = $vEvent->getAttribute('X-ATTENDEE'); $params = $vEvent->getAttribute('X-ATTENDEE', true); } catch (Horde_Icalendar_Exception $e) { } } } if ($attendee) { if (!is_array($attendee)) { $attendee = array($attendee); } if (!is_array($params)) { $params = array($params); } for ($i = 0; $i < count($attendee); ++$i) { $attendee[$i] = str_replace(array('MAILTO:', 'mailto:'), '', $attendee[$i]); $tmp = new Horde_Mail_Rfc822_Address($attendee[$i]); $email = $tmp->bare_address; // Default according to rfc2445: $attendance = Kronolith::PART_REQUIRED; // vCalendar 2.0 style: if (!empty($params[$i]['ROLE'])) { switch ($params[$i]['ROLE']) { case 'OPT-PARTICIPANT': $attendance = Kronolith::PART_OPTIONAL; break; case 'NON-PARTICIPANT': $attendance = Kronolith::PART_NONE; break; } } // vCalendar 1.0 style; if (!empty($params[$i]['EXPECT'])) { switch ($params[$i]['EXPECT']) { case 'REQUEST': $attendance = Kronolith::PART_OPTIONAL; break; case 'FYI': $attendance = Kronolith::PART_NONE; break; } } $response = Kronolith::RESPONSE_NONE; if (empty($params[$i]['PARTSTAT']) && !empty($params[$i]['STATUS'])) { $params[$i]['PARTSTAT'] = $params[$i]['STATUS']; } if (!empty($params[$i]['PARTSTAT'])) { switch ($params[$i]['PARTSTAT']) { case 'ACCEPTED': $response = Kronolith::RESPONSE_ACCEPTED; break; case 'DECLINED': $response = Kronolith::RESPONSE_DECLINED; break; case 'TENTATIVE': $response = Kronolith::RESPONSE_TENTATIVE; break; } } $name = isset($params[$i]['CN']) ? $params[$i]['CN'] : null; $this->addAttendee($email, $attendance, $response, $name); } } $this->_handlevEventRecurrence($vEvent); $this->initialized = true; }
/** * Returns a list of groups which have have certain permissions on a * share. * * @param string $scope The name of the share root, e.g. the * application that the share belongs to. * @param string $shareName The share's name. * @param array $permissions A list of permissions (show, read, edit, * delete). * * @return array List of groups with the specified permissions. * @throws Horde_Exception */ public function listGroupsOfShare($scope, $shareName, $permissions) { if (!$GLOBALS['registry']->isAdmin()) { throw new Horde_Exception(_("You are not allowed to list groups of shares.")); } $shares = $GLOBALS['injector']->getInstance('Horde_Core_Factory_Share')->create($scope); $share = $shares->getShare($shareName); $perm = 0; foreach ($permissions as $permission) { $permission = Horde_String::upper($permission); if (defined('Horde_Perms::' . $permission)) { $perm &= constant('Horde_Perms::' . $permission); } } return $share->listGroups($perm); }
public function vtodo2sif($vcard) { $iCal = new Horde_Icalendar(); if (!$iCal->parsevCalendar($vcard)) { return PEAR::raiseError('There was an error importing the data.'); } $components = $iCal->getComponents(); switch (count($components)) { case 0: return PEAR::raiseError('No data was found'); case 1: $content = $components[0]; break; default: return PEAR::raiseError('Multiple components found; only one is supported.'); } $hash['Complete'] = 0; $due = false; $attr = $content->getAllAttributes(); foreach ($attr as $item) { switch ($item['name']) { case 'SUMMARY': $hash['Subject'] = $item['value']; break; case 'DESCRIPTION': $hash['Body'] = $item['value']; break; case 'PRIORITY': if ($item['value'] == 1) { $hash['Importance'] = 2; } elseif ($item['value'] == 5) { $hash['Importance'] = 0; } else { $hash['Importance'] = 1; } break; case 'DTSTART': $hash['StartDate'] = Horde_Icalendar::_exportDateTime($item['value']); break; case 'DUE': $hash['DueDate'] = Horde_Icalendar::_exportDateTime($item['value']); $due = $item['value']; break; case 'AALARM': $hash['ReminderTime'] = $item['value']; $hash['ReminderSet'] = 1; break; case 'STATUS': $hash['Complete'] = $item['value'] == 'COMPLETED' ? 1 : 0; break; case 'CATEGORIES': $hash['Categories'] = $item['value']; break; case 'CLASS': switch (Horde_String::upper($item['value'])) { case 'PUBLIC': $hash['Sensitivity'] = 0; break; case 'PRIVATE': $hash['Sensitivity'] = 2; break; case 'CONFIDENTIAL': $hash['Sensitivity'] = 3; break; } break; } } if ($due && !isset($hash['ReminderSet'])) { // Parse VALARM components. foreach ($content->getComponents() as $component) { if ($component->getType() != 'vAlarm') { continue; } try { $trigger = $component->getAttribute('TRIGGER'); } catch (Horde_Icalendar_Exception $e) { continue; } if (is_array($trigger) || empty($trigger)) { continue; } $hash['ReminderSet'] = 1; $hash['ReminderTime'] = Horde_Icalendar::_exportDateTime($due - $trigger); } } return Horde_SyncMl_Device_sync4j::array2sif($hash, '<?xml version="1.0"?><task>', '</task>'); }
/** * Creates a task from a Horde_Icalendar_Vtodo object. * * @param Horde_Icalendar_Vtodo $vTodo The iCalendar data to update from. */ public function fromiCalendar(Horde_Icalendar_Vtodo $vTodo) { /* Owner is always current user. */ $this->owner = $GLOBALS['registry']->getAuth(); try { $name = $vTodo->getAttribute('SUMMARY'); if (!is_array($name)) { $this->name = $name; } } catch (Horde_Icalendar_Exception $e) { } try { $assignee = $vTodo->getAttribute('ORGANIZER'); if (!is_array($assignee)) { $this->assignee = $assignee; } } catch (Horde_Icalendar_Exception $e) { } try { $uid = $vTodo->getAttribute('UID'); if (!is_array($uid)) { $this->uid = $uid; } } catch (Horde_Icalendar_Exception $e) { } try { $relations = $vTodo->getAttribute('RELATED-TO'); if (!is_array($relations)) { $relations = array($relations); } $params = $vTodo->getAttribute('RELATED-TO', true); foreach ($relations as $id => $relation) { if (empty($params[$id]['RELTYPE']) || Horde_String::upper($params[$id]['RELTYPE']) == 'PARENT') { $parent = $this->_storage->getByUID($relation); $this->parent_id = $parent->id; break; } } } catch (Horde_Icalendar_Exception $e) { } try { $start = $vTodo->getAttribute('DTSTART'); if (!is_array($start)) { // Date-Time field $this->start = $start; } else { // Date field $this->start = mktime(0, 0, 0, (int) $start['month'], (int) $start['mday'], (int) $start['year']); } } catch (Horde_Icalendar_Exception $e) { } try { $due = $vTodo->getAttribute('DUE'); if (is_array($due)) { $this->due = mktime(0, 0, 0, (int) $due['month'], (int) $due['mday'], (int) $due['year']); } elseif (!empty($due)) { $this->due = $due; } } catch (Horde_Icalendar_Exception $e) { } // vCalendar 1.0 alarms try { $alarm = $vTodo->getAttribute('AALARM'); if (!is_array($alarm) && !empty($alarm) && !empty($this->due)) { $this->alarm = intval(($this->due - $alarm) / 60); if ($this->alarm === 0) { // We don't support alarms exactly at due date. $this->alarm = 1; } } } catch (Horde_Icalendar_Exception $e) { } // @TODO: vCalendar 2.0 alarms try { $desc = $vTodo->getAttribute('DESCRIPTION'); if (!is_array($desc)) { $this->desc = $desc; } } catch (Horde_Icalendar_Exception $e) { } try { $priority = $vTodo->getAttribute('PRIORITY'); if (!is_array($priority)) { $this->priority = $priority; } } catch (Horde_Icalendar_Exception $e) { } try { $cat = $vTodo->getAttribute('CATEGORIES'); if (!is_array($cat)) { $this->tags = $cat; } } catch (Horde_Icalendar_Exception $e) { } try { $status = $vTodo->getAttribute('STATUS'); if (!is_array($status)) { $this->completed = !strcasecmp($status, 'COMPLETED'); } } catch (Horde_Icalendar_Exception $e) { } try { $class = $vTodo->getAttribute('CLASS'); if (!is_array($class)) { $class = Horde_String::upper($class); $this->private = $class == 'PRIVATE' || $class == 'CONFIDENTIAL'; } } catch (Horde_Icalendar_Exception $e) { } }
/** * Parses response text for response codes (RFC 2449 [8]). * * @param string $text The response text. * * @return object An object with the following properties: * - code: (string) The response code, if it exists. * - data: (string) The response code data, if it exists. * - text: (string) The human-readable response text. */ protected function _parseResponseCode($text) { $ret = new stdClass(); $text = trim($text); if ($text[0] === '[') { $pos = strpos($text, ' ', 2); $end_pos = strpos($text, ']', 2); if ($pos > $end_pos) { $ret->code = Horde_String::upper(substr($text, 1, $end_pos - 1)); } else { $ret->code = Horde_String::upper(substr($text, 1, $pos - 1)); $ret->data = substr($text, $pos + 1, $end_pos - $pos - 1); } $ret->text = trim(substr($text, $end_pos + 1)); } else { $ret->text = $text; } return $ret; }
/** * Return the rendered inline version of the Horde_Mime_Part object. * * @return array See parent::render(). */ protected function _renderInline() { $browser = $this->getConfigParam('browser'); $notification = $this->getConfigParam('notification'); $prefs = $this->getConfigParam('prefs'); $registry = $this->getConfigParam('registry'); $data = $this->_mimepart->getContents(); $html = ''; $title = Horde_Core_Translation::t("vCard"); $iCal = new Horde_Icalendar(); if (!$iCal->parsevCalendar($data, 'VCALENDAR', $this->_mimepart->getCharset())) { $notification->push(Horde_Core_Translation::t("There was an error reading the contact data."), 'horde.error'); } if (Horde_Util::getFormData('import') && Horde_Util::getFormData('source') && $registry->hasMethod('contacts/import')) { $source = Horde_Util::getFormData('source'); $count = 0; foreach ($iCal->getComponents() as $c) { if ($c->getType() == 'vcard') { try { $registry->call('contacts/import', array($c, null, $source)); ++$count; } catch (Horde_Exception $e) { $notification->push(Horde_Core_Translation::t("There was an error importing the contact data:") . ' ' . $e->getMessage(), 'horde.error'); } } } $notification->push(sprintf(Horde_Core_Translation::ngettext("%d contact was successfully added to your address book.", "%d contacts were successfully added to your address book.", $count), $count), 'horde.success'); } $html .= '<table class="horde-table" style="width:100%">'; foreach ($iCal->getComponents() as $i => $vc) { if ($i > 0) { $html .= '<tr><td colspan="2"> </td></tr>'; } $addresses = $vc->getAllAttributes('EMAIL'); $html .= '<tr><td colspan="2" class="header">'; if (($fullname = $vc->getAttributeDefault('FN', false)) === false) { $fullname = count($addresses) ? $addresses[0]['value'] : Horde_Core_Translation::t("[No Label]"); } $html .= htmlspecialchars($fullname) . '</td></tr>'; $n = $vc->printableName(); if (!empty($n)) { $html .= $this->_row(Horde_Core_Translation::t("Name"), $n); } try { $html .= $this->_row(Horde_Core_Translation::t("Alias"), implode("\n", $vc->getAttributeValues('ALIAS'))); } catch (Horde_Icalendar_Exception $e) { } try { $birthdays = $vc->getAttributeValues('BDAY'); $birthday = new Horde_Date($birthdays[0]); $html .= $this->_row(Horde_Core_Translation::t("Birthday"), $birthday->strftime($prefs->getValue('date_format'))); } catch (Horde_Icalendar_Exception $e) { } $photos = $vc->getAllAttributes('PHOTO'); foreach ($photos as $p => $photo) { if (isset($photo['params']['VALUE']) && Horde_String::upper($photo['params']['VALUE']) == 'URI') { $html .= $this->_row(Horde_Core_Translation::t("Photo"), '<img src="' . htmlspecialchars($photo['value']) . '" />', false); } elseif (isset($photo['params']['ENCODING']) && Horde_String::upper($photo['params']['ENCODING']) == 'B' && isset($photo['params']['TYPE'])) { if ($browser->hasFeature('datauri') === true || $browser->hasFeature('datauri') >= strlen($photo['value'])) { $html .= $this->_row(Horde_Core_Translation::t("Photo"), '<img src="' . Horde_Url_Data::create($photo['params']['TYPE'], base64_decode($photo['value'])) . '" />', false); } elseif ($this->_imageUrl) { $html .= $this->_row(Horde_Core_Translation::t("Photo"), '<img src="' . $this->_imageUrl->add(array('c' => $i, 'p' => $p)) . '" />', false); } } } $labels = $vc->getAllAttributes('LABEL'); foreach ($labels as $label) { if (isset($label['params']['TYPE'])) { if (!is_array($label['params']['TYPE'])) { $label['params']['TYPE'] = array($label['params']['TYPE']); } } else { $label['params']['TYPE'] = array_keys($label['params']); } $types = array(); foreach ($label['params']['TYPE'] as $type) { switch (Horde_String::upper($type)) { case 'HOME': $types[] = Horde_Core_Translation::t("Home Address"); break; case 'WORK': $types[] = Horde_Core_Translation::t("Work Address"); break; case 'DOM': $types[] = Horde_Core_Translation::t("Domestic Address"); break; case 'INTL': $types[] = Horde_Core_Translation::t("International Address"); break; case 'POSTAL': $types[] = Horde_Core_Translation::t("Postal Address"); break; case 'PARCEL': $types[] = Horde_Core_Translation::t("Parcel Address"); break; case 'PREF': $types[] = Horde_Core_Translation::t("Preferred Address"); break; } } if (!count($types)) { $types = array(Horde_Core_Translation::t("Address")); } $html .= $this->_row(implode('/', $types), $label['value']); } $adrs = $vc->getAllAttributes('ADR'); foreach ($adrs as $item) { if (isset($item['params']['TYPE'])) { if (!is_array($item['params']['TYPE'])) { $item['params']['TYPE'] = array($item['params']['TYPE']); } } else { $item['params']['TYPE'] = array_keys($item['params']); } $address = $item['values']; $a = array(); $a_list = array(Horde_Icalendar_Vcard::ADR_STREET, Horde_Icalendar_Vcard::ADR_LOCALITY, Horde_Icalendar_Vcard::ADR_REGION, Horde_Icalendar_Vcard::ADR_POSTCODE, Horde_Icalendar_Vcard::ADR_COUNTRY); foreach ($a_list as $val) { if (isset($address[$val])) { $a[] = $address[$val]; } } $types = array(); foreach ($item['params']['TYPE'] as $type) { switch (Horde_String::upper($type)) { case 'HOME': $types[] = Horde_Core_Translation::t("Home Address"); break; case 'WORK': $types[] = Horde_Core_Translation::t("Work Address"); break; case 'DOM': $types[] = Horde_Core_Translation::t("Domestic Address"); break; case 'INTL': $types[] = Horde_Core_Translation::t("International Address"); break; case 'POSTAL': $types[] = Horde_Core_Translation::t("Postal Address"); break; case 'PARCEL': $types[] = Horde_Core_Translation::t("Parcel Address"); break; case 'PREF': $types[] = Horde_Core_Translation::t("Preferred Address"); break; } } if (!count($types)) { $types = array(Horde_Core_Translation::t("Address")); } $html .= $this->_row(implode('/', $types), implode("\n", $a)); } $numbers = $vc->getAllAttributes('TEL'); foreach ($numbers as $number) { if (isset($number['params']['TYPE'])) { if (!is_array($number['params']['TYPE'])) { $number['params']['TYPE'] = array($number['params']['TYPE']); } foreach ($number['params']['TYPE'] as $type) { $number['params'][Horde_String::upper($type)] = true; } } if (isset($number['params']['FAX'])) { $html .= $this->_row(Horde_Core_Translation::t("Fax"), $number['value']); } else { if (isset($number['params']['HOME'])) { $html .= $this->_row(Horde_Core_Translation::t("Home Phone"), $number['value']); } elseif (isset($number['params']['WORK'])) { $html .= $this->_row(Horde_Core_Translation::t("Work Phone"), $number['value']); } elseif (isset($number['params']['CELL'])) { $html .= $this->_row(Horde_Core_Translation::t("Cell Phone"), $number['value']); } else { $html .= $this->_row(Horde_Core_Translation::t("Phone"), $number['value']); } } } $emails = array(); foreach ($addresses as $address) { if (isset($address['params']['TYPE'])) { if (!is_array($address['params']['TYPE'])) { $address['params']['TYPE'] = array($address['params']['TYPE']); } foreach ($address['params']['TYPE'] as $type) { $address['params'][Horde_String::upper($type)] = true; } } $email = '<a href="'; if ($registry->hasMethod('mail/compose')) { $email .= $registry->call('mail/compose', array(array('to' => $address['value']))); } else { $email .= 'mailto:' . htmlspecialchars($address['value']); } $email .= '">' . htmlspecialchars($address['value']) . '</a>'; if (isset($address['params']['PREF'])) { array_unshift($emails, $email); } else { $emails[] = $email; } } if (count($emails)) { $html .= $this->_row(Horde_Core_Translation::t("Email"), implode("\n", $emails), false); } try { $title = $vc->getAttributeValues('TITLE'); $html .= $this->_row(Horde_Core_Translation::t("Title"), $title[0]); } catch (Horde_Icalendar_Exception $e) { } try { $role = $vc->getAttributeValues('ROLE'); $html .= $this->_row(Horde_Core_Translation::t("Role"), $role[0]); } catch (Horde_Icalendar_Exception $e) { } try { $org = $vc->getAttributeValues('ORG'); $html .= $this->_row(Horde_Core_Translation::t("Company"), $org[0]); if (isset($org[1])) { $html .= $this->_row(Horde_Core_Translation::t("Department"), $org[1]); } } catch (Horde_Icalendar_Exception $e) { } try { $notes = $vc->getAttributeValues('NOTE'); $html .= $this->_row(Horde_Core_Translation::t("Notes"), $notes[0]); } catch (Horde_Icalendar_Exception $e) { } try { $url = $vc->getAttributeValues('URL'); $html .= $this->_row(Horde_Core_Translation::t("URL"), '<a href="' . htmlspecialchars($url[0]) . '" target="_blank">' . htmlspecialchars($url[0]) . '</a>', false); } catch (Horde_Icalendar_Exception $e) { } } $html .= '</table>'; if ($registry->hasMethod('contacts/import') && $registry->hasMethod('contacts/sources')) { $html .= '<div class="horde-form-buttons"><form action="' . Horde::selfUrl() . '" method="get" name="vcard_import" id="vcard_import">' . Horde_Util::formInput(); foreach ($_GET as $key => $val) { $html .= '<input type="hidden" name="' . htmlspecialchars($key) . '" value="' . htmlspecialchars($val) . '" />'; } $sources = $registry->call('contacts/sources', array(true)); if (count($sources) > 1) { $html .= '<input type="submit" class="horde-default" name="import" value="' . Horde_Core_Translation::t("Add to address book:") . '" />' . ' <label for="add_source" class="hidden">' . Horde_Core_Translation::t("Address Book") . '</label>' . '<select id="add_source" name="source">'; foreach ($sources as $key => $label) { $selected = $key == $prefs->getValue('add_source') ? ' selected="selected"' : ''; $html .= '<option value="' . htmlspecialchars($key) . '"' . $selected . '>' . htmlspecialchars($label) . '</option>'; } $html .= '</select>'; } else { reset($sources); $html .= '<input type="submit" class="horde-default" name="import" value="' . Horde_Core_Translation::t("Add to my address book") . '" />' . '<input type="hidden" name="source" value="' . htmlspecialchars(key($sources)) . '" />'; } $html .= '</form></div>'; } Horde::startBuffer(); $notification->notify(array('listeners' => 'status')); return $this->_renderReturn(Horde::endBuffer() . $html, 'text/html; charset=' . $this->getConfigParam('charset')); }