diff --git a/addressbook/inc/class.addressbook_sif.inc.php b/addressbook/inc/class.addressbook_sif.inc.php deleted file mode 100644 index c8e76e8d20..0000000000 --- a/addressbook/inc/class.addressbook_sif.inc.php +++ /dev/null @@ -1,315 +0,0 @@ - - * @author Ralf Becker - * @author Joerg Lehrke - * @package addressbook - * @subpackage export - * @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License - * @version $Id$ - */ - -class addressbook_sif extends addressbook_bo -{ - var $sifMapping = array( - 'Anniversary' => '', - 'AssistantName' => 'assistent', - 'AssistantTelephoneNumber' => 'tel_assistent', - 'BillingInformation' => '', - 'Birthday' => 'bday', - 'Body' => 'note', - 'Business2TelephoneNumber' => '', - 'BusinessAddressCity' => 'adr_one_locality', - 'BusinessAddressCountry' => 'adr_one_countryname', - 'BusinessAddressPostalCode' => 'adr_one_postalcode', - 'BusinessAddressPostOfficeBox' => 'adr_one_street2', - 'BusinessAddressState' => 'adr_one_region', - 'BusinessAddressStreet' => 'adr_one_street', - 'BusinessFaxNumber' => 'tel_fax', - 'BusinessTelephoneNumber' => 'tel_work', - 'CallbackTelephoneNumber' => '', - 'CarTelephoneNumber' => 'tel_car', - 'Categories' => 'cat_id', - 'Children' => '', - 'Companies' => '', - 'CompanyMainTelephoneNumber' => '', - 'CompanyName' => 'org_name', - 'ComputerNetworkName' => '', - 'Department' => 'org_unit', - 'Email1Address' => 'email', - 'Email1AddressType' => '', - 'Email2Address' => 'email_home', - 'Email2AddressType' => '', - 'Email3Address' => '', - 'Email3AddressType' => '', - 'FileAs' => 'n_fileas', - 'FirstName' => 'n_given', - 'Hobby' => '', - 'Home2TelephoneNumber' => '', - 'HomeAddressCity' => 'adr_two_locality', - 'HomeAddressCountry' => 'adr_two_countryname', - 'HomeAddressPostalCode' => 'adr_two_postalcode', - 'HomeAddressPostOfficeBox' => 'adr_two_street2', - 'HomeAddressState' => 'adr_two_region', - 'HomeAddressStreet' => 'adr_two_street', - 'HomeFaxNumber' => 'tel_fax_home', - 'HomeTelephoneNumber' => 'tel_home', - 'Importance' => '', - 'Initials' => '', - 'JobTitle' => 'title', - 'Language' => '', - 'LastName' => 'n_family', - 'ManagerName' => '', - 'MiddleName' => 'n_middle', - 'Mileage' => '', - 'MobileTelephoneNumber' => 'tel_cell', - 'NickName' => '', - 'OfficeLocation' => 'room', - 'OrganizationalIDNumber' => '', - 'OtherAddressCity' => '', - 'OtherAddressCountry' => '', - 'OtherAddressPostalCode' => '', - 'OtherAddressPostOfficeBox' => '', - 'OtherAddressState' => '', - 'OtherAddressStreet' => '', - 'OtherFaxNumber' => '', - 'OtherTelephoneNumber' => 'tel_other', - 'PagerNumber' => 'tel_pager', - 'PrimaryTelephoneNumber' => 'tel_prefer', - 'Profession' => 'role', - 'RadioTelephoneNumber' => '', - 'Sensitivity' => 'private', - 'Spouse' => '', - 'Subject' => '', - 'Suffix' => 'n_suffix', - 'TelexNumber' => '', - 'Title' => 'n_prefix', - 'WebPage' => 'url', - 'YomiCompanyName' => '', - 'YomiFirstName' => '', - 'YomiLastName' => '', - 'HomeWebPage' => 'url_home', - 'Folder' => '', - ); - - // standard headers - const xml_decl = ''; - const SIF_decl = '1.1'; - - function startElement($_parser, $_tag, $_attributes) - { - } - - function endElement($_parser, $_tag) - { - if (!empty($this->sifMapping[$_tag])) - { - $this->contact[$this->sifMapping[$_tag]] = trim($this->sifData); - } - unset($this->sifData); - } - - function characterData($_parser, $_data) - { - $this->sifData .= $_data; - } - - function siftoegw($sifData) - { - - #$tmpfname = tempnam('/tmp/sync/contents','sifc_'); - - #$handle = fopen($tmpfname, "w"); - #fwrite($handle, $sifData); - #fclose($handle); - - // Horde::logMessage("SyncML siftoegw:\n$sifData", __FILE__, __LINE__, PEAR_LOG_DEBUG); - - $this->xml_parser = xml_parser_create('UTF-8'); - xml_set_object($this->xml_parser, $this); - xml_parser_set_option($this->xml_parser, XML_OPTION_CASE_FOLDING, false); - xml_set_element_handler($this->xml_parser, "startElement", "endElement"); - xml_set_character_data_handler($this->xml_parser, "characterData"); - $this->strXmlData = xml_parse($this->xml_parser, $sifData); - if (!$this->strXmlData) - { - error_log(sprintf("XML error: %s at line %d", - xml_error_string(xml_get_error_code($this->xml_parser)), - xml_get_current_line_number($this->xml_parser))); - return false; - } - - foreach ($this->contact as $key => $value) - { - $value = preg_replace('/<\!\[CDATA\[(.+)\]\]>/Usim', '$1', $value); - $value = $GLOBALS['egw']->translation->convert($value, 'utf-8'); - switch ($key) { - case 'cat_id': - if (!empty($value)) - { - $categories1 = explode(',', $value); - $categories2 = explode(';', $value); - $finalContact[$key] = count($categories1) > count($categories2) ? $categories1 : $categories2; - } - break; - - case 'private': - $finalContact[$key] = (int) ($value > 0); // eGW private is 0 (public) or 1 (private), SIF seems to use 0 and 2 - break; - - default: - $finalContact[$key] = str_replace("\r\n", "\n", $value); - break; - } - } - - $this->fixup_contact($finalContact); - // Horde::logMessage("SyncML siftoegw: " . print_r($finalContact, true), __FILE__, __LINE__, PEAR_LOG_DEBUG); - return $finalContact; - } - - /** - * Search an exactly matching entry (used for slow sync) - * - * @param string $_sifdata - * @return array of matching contact-ids - */ - function search($_sifdata, $contentID=null, $relax=false) - { - $result = array(); - - if (($contact = $this->siftoegw($_sifdata))) - { - if ($contentID) - { - $contact['contact_id'] = $contentID; - } - $result = $this->find_contact($contact, $relax); - } - return $result; - } - - /** - * import a vard into addressbook - * - * @return int contact id - * @param string $_vcard the vcard - * @param int/string $_abID=null the internal addressbook id or !$_abID for a new enty - * @param boolean $merge=false merge data with existing entry - */ - function addSIF($_sifdata, $_abID=null, $merge=false) - { - if (!$contact = $this->siftoegw($_sifdata)) - { - return false; - } - - if ($_abID) - { - if (($old_contact = $this->read($_abID))) - { - if ($merge) - { - foreach ($contact as $key => $value) - { - if (!empty($old_contact[$key])) - { - $contact[$key] = $old_contact[$key]; - } - } - } - else - { - if (isset($old_contact['account_id'])) - { - $contact['account_id'] = $old_contact['account_id']; - } - if (is_array($contact['cat_id'])) - { - $contact['cat_id'] = implode(',',$this->find_or_add_categories($contact['cat_id'], $_abID)); - } - else - { - // restore from orignal - $contact['cat_id'] = $old_contact['cat_id']; - } - } - } - // update entry - $contact['id'] = $_abID; - } - else - { - if (is_array($contact['cat_id'])) - { - $contact['cat_id'] = implode(',',$this->find_or_add_categories($contact['cat_id'], -1)); - } - } - return $this->save($contact); - } - - /** - * return a sifc - * - * @param int $_id the id of the contact - * @return string containing the vcard - */ - function getSIF($_id) - { - $sysCharSet = $GLOBALS['egw']->translation->charset(); - - $fields = array_unique(array_values($this->sifMapping)); - sort($fields); - - if (!($entry = $this->read($_id))) return false; - - $sifContact = self::xml_decl . "\n" . self::SIF_decl; - - #error_log(print_r($entry,true)); - - // fillup some defaults such as n_fn and n_fileas is needed - $this->fixup_contact($entry); - - foreach ($this->sifMapping as $sifField => $egwField) - { - if (empty($egwField)) continue; - - #error_log("$sifField => $egwField"); - #error_log('VALUE1: '.$entry[0][$egwField]); - $value = $GLOBALS['egw']->translation->convert($entry[$egwField], $sysCharSet, 'utf-8'); - #error_log('VALUE2: '.$value); - - switch ($sifField) - { - case 'Sensitivity': - $value = 2 * $value; // eGW private is 0 (public) or 1 (private) - $sifContact .= "<$sifField>$value"; - break; - - case 'Folder': - # skip currently. This is the folder where Outlook stores the contact. - #$sifContact .= "<$sifField>/"; - break; - - case 'Categories': - if (!empty($value)) { - $value = implode(", ", $this->get_categories($value)); - $value = $GLOBALS['egw']->translation->convert($value, $sysCharSet, 'utf-8'); - } else { - break; - } - - default: - $value = @htmlspecialchars(trim($value), ENT_NOQUOTES, 'utf-8'); - $sifContact .= "<$sifField>$value"; - break; - } - } - $sifContact .= ""; - - return $sifContact; - } -} diff --git a/addressbook/inc/class.addressbook_vcal.inc.php b/addressbook/inc/class.addressbook_vcal.inc.php index 2c481cb711..a007c8bec1 100644 --- a/addressbook/inc/class.addressbook_vcal.inc.php +++ b/addressbook/inc/class.addressbook_vcal.inc.php @@ -12,9 +12,6 @@ * @version $Id$ */ -require_once EGW_SERVER_ROOT.'/phpgwapi/inc/horde/lib/core.php'; -require_once(EGW_SERVER_ROOT.'/phpgwapi/inc/horde/Horde/SyncML/State.php'); - /** * Addressbook - vCard parser * @@ -75,7 +72,7 @@ class addressbook_vcal extends addressbook_bo 'REV' => array('modified'), //set for Apple: 'X-ABSHOWAS' => array('fileas_type'), // Horde vCard class uses uppercase prop-names! ); - + var $supportedFields; /** @@ -130,8 +127,8 @@ class addressbook_vcal extends addressbook_bo * import a vard into addressbook * * @param string $_vcard the vcard - * @param int/string $_abID=null the internal addressbook id or !$_abID for a new enty - * @param boolean $merge=false merge data with existing entry + * @param int/string $_abID =null the internal addressbook id or !$_abID for a new enty + * @param boolean $merge =false merge data with existing entry * @param string $charset The encoding charset for $text. Defaults to * utf-8 for new format, iso-8859-1 for old format. * @return int contact id @@ -146,7 +143,7 @@ class addressbook_vcal extends addressbook_bo { if ($merge) { - foreach ($contact as $key => $value) + foreach (array_keys($contact) as $key) { if (!empty($old_contact[$key])) { @@ -197,17 +194,13 @@ class addressbook_vcal extends addressbook_bo * return a vcard * * @param int/string $_id the id of the contact - * @param string $_charset='UTF-8' encoding of the vcard, default UTF-8 - * @param boolean $extra_charset_attribute=true GroupDAV/CalDAV dont need the charset attribute and some clients have problems with it + * @param string $_charset ='UTF-8' encoding of the vcard, default UTF-8 + * @param boolean $extra_charset_attribute =true GroupDAV/CalDAV dont need the charset attribute and some clients have problems with it * @return string containing the vcard */ function getVCard($_id,$_charset='UTF-8',$extra_charset_attribute=true) { - require_once(EGW_SERVER_ROOT.'/phpgwapi/inc/horde/Horde/iCalendar/vcard.php'); - - #Horde::logMessage("vCalAddressbook clientProperties:\n" . print_r($this->clientProperties, true), __FILE__, __LINE__, PEAR_LOG_DEBUG); - - $vCard = new Horde_iCalendar_vcard($this->version); + $vCard = new Horde_Icalendar_Vcard($this->version); $vCard->setAttribute('PRODID','-//EGroupware//NONSGML EGroupware Addressbook '.$GLOBALS['egw_info']['apps']['phpgwapi']['version'].'//'. strtoupper($GLOBALS['egw_info']['user']['preferences']['common']['lang'])); @@ -525,7 +518,7 @@ class addressbook_vcal extends addressbook_bo if (is_array($_supportedFields)) $this->supportedFields = $_supportedFields; } - + function setDatabaseFields($_databaseFields) { if (is_array($_databaseFields)) $this->databaseFields = $_databaseFields; @@ -551,7 +544,7 @@ class addressbook_vcal extends addressbook_bo array2string($_vcard)."\n",3,$this->logfile); } - require_once(EGW_SERVER_ROOT.'/phpgwapi/inc/horde/Horde/iCalendar.php'); +// require_once(EGW_SERVER_ROOT.'/phpgwapi/inc/horde/Horde/iCalendar.php'); if(!($_vcard instanceof Horde_iCalendar)) { @@ -1053,14 +1046,12 @@ class addressbook_vcal extends addressbook_bo * return a groupVCard * * @param array $list values for 'list_uid', 'list_name', 'list_modified', 'members' - * @param string $version='3.0' vcard version + * @param string $version ='3.0' vcard version * @return string containing the vcard */ function getGroupVCard(array $list,$version='3.0') { - require_once(EGW_SERVER_ROOT.'/phpgwapi/inc/horde/Horde/iCalendar/vcard.php'); - - $vCard = new Horde_iCalendar_vcard($version); + $vCard = new Horde_Icalendar_Vcard($version); $vCard->setAttribute('PRODID','-//EGroupware//NONSGML EGroupware Addressbook '.$GLOBALS['egw_info']['apps']['phpgwapi']['version'].'//'. strtoupper($GLOBALS['egw_info']['user']['preferences']['common']['lang'])); diff --git a/calendar/inc/class.calendar_ical.inc.php b/calendar/inc/class.calendar_ical.inc.php index 7a19cf4436..dcbfae2f95 100644 --- a/calendar/inc/class.calendar_ical.inc.php +++ b/calendar/inc/class.calendar_ical.inc.php @@ -12,8 +12,6 @@ * @version $Id$ */ -require_once EGW_SERVER_ROOT.'/phpgwapi/inc/horde/lib/core.php'; - /** * iCal import and export via Horde iCalendar classes * @@ -178,7 +176,7 @@ class calendar_ical extends calendar_boupdate parent::__construct(); if ($this->log) $this->logfile = $GLOBALS['egw_info']['server']['temp_dir']."/log-vcal"; $this->clientProperties = $_clientProperties; - $this->vCalendar = new Horde_iCalendar; + $this->vCalendar = new Horde_Icalendar; $this->addressbook = new addressbook_bo; } @@ -187,12 +185,12 @@ class calendar_ical extends calendar_boupdate * Exports one calendar event to an iCalendar item * * @param int|array $events (array of) cal_id or array of the events with timestamps in server time - * @param string $version='1.0' could be '2.0' too - * @param string $method='PUBLISH' - * @param int $recur_date=0 if set export the next recurrence at or after the timestamp, + * @param string $version ='1.0' could be '2.0' too + * @param string $method ='PUBLISH' + * @param int $recur_date =0 if set export the next recurrence at or after the timestamp, * default 0 => export whole series (or events, if not recurring) - * @param string $principalURL='' Used for CalDAV exports - * @param string $charset='UTF-8' encoding of the vcalendar, default UTF-8 + * @param string $principalURL ='' Used for CalDAV exports + * @param string $charset ='UTF-8' encoding of the vcalendar, default UTF-8 * @return string|boolean string with iCal or false on error (e.g. no permission to read the event) */ function &exportVCal($events, $version='1.0', $method='PUBLISH', $recur_date=0, $principalURL='', $charset='UTF-8') @@ -231,7 +229,7 @@ class calendar_ical extends calendar_boupdate $version = '2.0'; } - $vcal = new Horde_iCalendar; + $vcal = new Horde_Icalendar; $vcal->setAttribute('PRODID','-//EGroupware//NONSGML EGroupware Calendar '.$GLOBALS['egw_info']['apps']['calendar']['version'].'//'. strtoupper($GLOBALS['egw_info']['user']['preferences']['common']['lang'])); $vcal->setAttribute('VERSION', $version); @@ -330,7 +328,7 @@ class calendar_ical extends calendar_boupdate if ($this->log) { error_log(__FILE__.'['.__LINE__.'] '.__METHOD__. - "($_id, $recurrence) Gratuitous pseudo exception, skipped ...\n", + "(, $recurrence) Gratuitous pseudo exception, skipped ...\n", 3,$this->logfile); } continue; // unsupported status only exception @@ -377,7 +375,7 @@ class calendar_ical extends calendar_boupdate } } - $vevent = Horde_iCalendar::newComponent('VEVENT', $vcal); + $vevent = Horde_Icalendar::newComponent('VEVENT', $vcal); $parameters = $attributes = $values = array(); if ($this->productManufacturer == 'sonyericsson') @@ -429,6 +427,7 @@ class calendar_ical extends calendar_boupdate case 'ATTENDEE': foreach ((array)$event['participants'] as $uid => $status) { + $quantity = $role = null; calendar_so::split_status($status, $quantity, $role); // do not include event owner/ORGANIZER as participant in his own calendar, if he is only participant if (count($event['participants']) == 1 && $event['owner'] == $uid) continue; @@ -442,10 +441,9 @@ class calendar_ical extends calendar_boupdate error_log(__FILE__.'['.__LINE__.'] '.__METHOD__ . '()attendee:' . array2string($info) ."\n",3,$this->logfile); } - $participantCN = trim(empty($info['cn']) ? $info['name'] : $info['cn']); $participantCN = str_replace(array('\\', ',', ';', ':'), array('\\\\', '\\,', '\\;', '\\:'), - $participantCN); + trim(empty($info['cn']) ? $info['name'] : $info['cn'])); if ($version == '1.0') { $participantURL = trim('"' . $participantCN . '"' . (empty($info['email']) ? '' : ' <' . $info['email'] .'>')); @@ -861,7 +859,7 @@ class calendar_ical extends calendar_boupdate $attributes['LAST-MODIFIED'] = $event['modified']; } $attributes['DTSTAMP'] = time(); - foreach ((array)$event['alarm'] as $alarmID => $alarmData) + foreach ((array)$event['alarm'] as $alarmData) { // skip over alarms that don't have the minimum required info if (!$alarmData['offset'] && !$alarmData['time']) continue; @@ -928,7 +926,7 @@ class calendar_ical extends calendar_boupdate $alarmData['offset'] = false; } - $valarm = Horde_iCalendar::newComponent('VALARM',$vevent); + $valarm = Horde_Icalendar::newComponent('VALARM',$vevent); if ($alarmData['offset'] !== false) { $valarm->setAttribute('TRIGGER', -$alarmData['offset'], @@ -1122,6 +1120,7 @@ class calendar_ical extends calendar_boupdate date_default_timezone_set($tzid); + $msg = null; foreach ($events as $event) { if (!is_array($event)) continue; // the iterator may return false @@ -1390,8 +1389,7 @@ class calendar_ical extends calendar_boupdate // They can now only remove themselfs, if that is desired, after storing the event first. || !isset($event['participants'][$event['owner']])) { - $status = $event['owner'] == $this->user ? 'A' : 'U'; - $status = calendar_so::combine_status($status, 1, 'CHAIR'); + $status = calendar_so::combine_status($event['owner'] == $this->user ? 'A' : 'U', 1, 'CHAIR'); if (!is_array($event['participants'])) $event['participants'] = array(); $event['participants'][$event['owner']] = $status; } @@ -1769,9 +1767,9 @@ class calendar_ical extends calendar_boupdate /** * get the value of an attribute by its name * - * @param array $attributes + * @param array $components * @param string $name eg. 'DTSTART' - * @param string $what='value' + * @param string $what ='value' * @return mixed */ static function _get_attribute($components,$name,$what='value') @@ -2150,7 +2148,7 @@ class calendar_ical extends calendar_boupdate * Convert vCalendar data in EGw events * * @param string|resource $_vcalData - * @param string $principalURL='' Used for CalDAV imports + * @param string $principalURL ='' Used for CalDAV imports * @param string $charset The encoding charset for $text. Defaults to * utf-8 for new format, iso-8859-1 for old format. * @return Iterator|array|boolean Iterator if resource given or array of events on success, false on failure @@ -2183,7 +2181,7 @@ class calendar_ical extends calendar_boupdate date_default_timezone_set($tzid); $events = array(); - $vcal = new Horde_iCalendar; + $vcal = new Horde_Icalendar; if (!$vcal->parsevCalendar($_vcalData, 'VCALENDAR', $charset)) { if ($this->log) @@ -2194,9 +2192,7 @@ class calendar_ical extends calendar_boupdate date_default_timezone_set($GLOBALS['egw_info']['server']['server_timezone']); return false; } - $version = $vcal->getAttribute('VERSION'); - - foreach ($vcal->getComponents() as $n => $component) + foreach ($vcal->getComponents() as $component) { if (($event = $this->_ical2egw_callback($component,$this->tzid,$principalURL))) { @@ -2209,14 +2205,14 @@ class calendar_ical extends calendar_boupdate } /** - * Callback for egw_ical_iterator to convert Horde_iCalendar_vevent to EGw event array + * Callback for egw_ical_iterator to convert Horde_iCalendar_Vevent to EGw event array * * @param Horde_iCalendar $component * @param string $tzid timezone - * @param string $principalURL='' Used for CalDAV imports - * @return array|boolean event array or false if $component is no Horde_iCalendar_vevent + * @param string $principalURL ='' Used for CalDAV imports + * @return array|boolean event array or false if $component is no Horde_Icalendar_Vevent */ - function _ical2egw_callback(Horde_iCalendar $component, $tzid, $principalURL='') + function _ical2egw_callback(Horde_Icalendar $component, $tzid, $principalURL='') { //unset($component->_container); _debug_array($component); @@ -2225,7 +2221,7 @@ class calendar_ical extends calendar_boupdate error_log(__FILE__.'['.__LINE__.'] '.__METHOD__.'() '.get_class($component)." found\n",3,$this->logfile); } - if (!is_a($component, 'Horde_iCalendar_vevent') || + if (!is_a($component, 'Horde_Icalendar_Vevent') || !($event = $this->vevent2egw($component, $component->_container->getAttribute('VERSION'), $this->supportedFields, $principalURL))) { return false; @@ -2246,7 +2242,7 @@ class calendar_ical extends calendar_boupdate $alarms = $event['alarm']; foreach ($component->getComponents() as $valarm) { - if (is_a($valarm, 'Horde_iCalendar_valarm')) + if (is_a($valarm, 'Horde_Icalendar_Valarm')) { $this->valarm2egw($alarms, $valarm); } @@ -2265,13 +2261,15 @@ class calendar_ical extends calendar_boupdate * @param array $component VEVENT * @param string $version vCal version (1.0/2.0) * @param array $supportedFields supported fields of the device - * @param string $principalURL='' Used for CalDAV imports, no longer used in favor of groupdav_principals::url2uid() - * @param string $check_component='Horde_iCalendar_vevent' + * @param string $principalURL ='' Used for CalDAV imports, no longer used in favor of groupdav_principals::url2uid() + * @param string $check_component ='Horde_Icalendar_Vevent' * * @return array|boolean event on success, false on failure */ - function vevent2egw(&$component, $version, $supportedFields, $principalURL='', $check_component='Horde_iCalendar_vevent') + function vevent2egw(&$component, $version, $supportedFields, $principalURL='', $check_component='Horde_Icalendar_Vevent') { + unset($principalURL); // not longer used, but required in function signature + if ($check_component && !is_a($component, $check_component)) { if ($this->log) @@ -2421,9 +2419,10 @@ class calendar_ical extends calendar_boupdate break; case 'DESCRIPTION': $vcardData['description'] = str_replace("\r\n", "\n", $attributes['value']); + $matches = null; if (preg_match('/\s*\[UID:(.+)?\]/Usm', $attributes['value'], $matches)) { - if (!isset($vCardData['uid']) + if (!isset($vcardData['uid']) && strlen($matches[1]) >= $minimum_uid_length) { $vcardData['uid'] = $matches[1]; @@ -2463,6 +2462,7 @@ class calendar_ical extends calendar_boupdate switch($type) { case 'D': // 1.0 + $recurenceMatches = null; if (preg_match('/D(\d+) #(\d+)/', $recurence, $recurenceMatches)) { $vcardData['recur_interval'] = $recurenceMatches[1]; @@ -2495,6 +2495,7 @@ class calendar_ical extends calendar_boupdate $days = explode(' ',trim($recurenceMatches[2])); } + $repeatMatches = null; if (preg_match('/#(\d+)/',$recurenceMatches[4],$repeatMatches)) { if ($repeatMatches[1]) $vcardData['recur_count'] = $repeatMatches[1]; @@ -2847,6 +2848,7 @@ class calendar_ical extends calendar_boupdate { // keep role 'CHAIR' from an external organizer, even if he is a regular participant with a different role // as this is currently the only way to store an external organizer and send him iMip responses + $q = $r = null; if (isset($vcardData['participants'][$uid]) && ($s=$vcardData['participants'][$uid]) && calendar_so::split_status($s, $q, $r) && $r == 'CHAIR') { @@ -3065,12 +3067,12 @@ class calendar_ical extends calendar_boupdate * Create a freebusy vCal for the given user(s) * * @param int $user account_id - * @param mixed $end=null end-date, default now+1 month - * @param boolean $utc=true if false, use severtime for dates - * @param string $charset='UTF-8' encoding of the vcalendar, default UTF-8 - * @param mixed $start=null default now - * @param string $method='PUBLISH' or eg. 'REPLY' - * @param array $extra=null extra attributes to add + * @param mixed $end =null end-date, default now+1 month + * @param boolean $utc =true if false, use severtime for dates + * @param string $charset ='UTF-8' encoding of the vcalendar, default UTF-8 + * @param mixed $start =null default now + * @param string $method ='PUBLISH' or eg. 'REPLY' + * @param array $extra =null extra attributes to add * X-CALENDARSERVER-MASK-UID can be used to not include an event specified by this uid as busy */ function freebusy($user,$end=null,$utc=true, $charset='UTF-8', $start=null, $method='PUBLISH', array $extra=null) @@ -3078,14 +3080,13 @@ class calendar_ical extends calendar_boupdate if (!$start) $start = time(); // default now if (!$end) $end = time() + 100*DAY_s; // default next 100 days - $vcal = new Horde_iCalendar; + $vcal = new Horde_Icalendar; $vcal->setAttribute('PRODID','-//EGroupware//NONSGML EGroupware Calendar '.$GLOBALS['egw_info']['apps']['calendar']['version'].'//'. strtoupper($GLOBALS['egw_info']['user']['preferences']['common']['lang'])); $vcal->setAttribute('VERSION','2.0'); $vcal->setAttribute('METHOD',$method); - $vfreebusy = Horde_iCalendar::newComponent('VFREEBUSY',$vcal); - if ($uid) $vfreebusy->setAttribute('UID', $uid); + $vfreebusy = Horde_Icalendar::newComponent('VFREEBUSY',$vcal); $attributes = array( 'DTSTAMP' => time(), diff --git a/calendar/inc/class.calendar_sif.inc.php b/calendar/inc/class.calendar_sif.inc.php deleted file mode 100644 index 7c6b5d5f1a..0000000000 --- a/calendar/inc/class.calendar_sif.inc.php +++ /dev/null @@ -1,1246 +0,0 @@ - - * @author Joerg Lehrke - * @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License - * @package calendar - * @subpackage export - * @version $Id$ - */ - -require_once EGW_SERVER_ROOT.'/phpgwapi/inc/horde/lib/core.php'; - -/** - * SIF Parser for SyncML - */ -class calendar_sif extends calendar_boupdate -{ - var $sifMapping = array( - 'Start' => 'start', - 'End' => 'end', - 'AllDayEvent' => 'alldayevent', - 'Attendees' => '', - 'BillingInformation' => '', - 'Body' => 'description', - 'BusyStatus' => '', - 'Categories' => 'category', - 'Companies' => '', - 'Importance' => 'priority', - 'IsRecurring' => 'isrecurring', - 'Location' => 'location', - 'MeetingStatus' => '', - 'Mileage' => '', - 'ReminderMinutesBeforeStart' => 'reminderstart', - 'ReminderSet' => 'reminderset', - 'ReminderSoundFile' => '', - 'ReminderOptions' => '', - 'ReminderInterval' => '', - 'ReminderRepeatCount' => '', - 'Exceptions' => '', - 'ReplyTime' => '', - 'Sensitivity' => 'public', - 'Subject' => 'title', - 'RecurrenceType' => 'recur_type', - 'Interval' => 'recur_interval', - 'MonthOfYear' => '', - 'DayOfMonth' => '', - 'DayOfWeekMask' => 'recur_weekmask', - 'Instance' => '', - 'PatternStartDate' => '', - 'NoEndDate' => 'recur_noenddate', - 'PatternEndDate' => 'recur_enddate', - 'Occurrences' => '', - ); - - /** - * the calendar event array for the XML Parser - */ - var $event; - - /** - * name and sorftware version of the Funambol client - * - * @var string - */ - var $productName = 'mozilla plugin'; - var $productSoftwareVersion = '0.3'; - - /** - * user preference: import all-day events as non blocking - * - * @var boolean - */ - var $nonBlockingAllday = false; - - /** - * user preference: attach UID entries to the DESCRIPTION - * - * @var boolean - */ - var $uidExtension = false; - - /** - * user preference: calendar to synchronize with - * - * @var int - */ - var $calendarOwner = 0; - - /** - * user preference: Use this timezone for import from and export to device - * - * @var string - */ - var $tzid = null; - - /** - * Device CTCap Properties - * - * @var array - */ - var $clientProperties; - - /** - * vCalendar Instance for parsing - * - * @var array - */ - var $vCalendar; - - /** - * Set Logging - * - * @var boolean - */ - var $log = false; - var $logfile="/tmp/log-sifcal"; - - - // constants for recurence type - const olRecursDaily = 0; - const olRecursWeekly = 1; - const olRecursMonthly = 2; - const olRecursMonthNth = 3; - const olRecursYearly = 5; - const olRecursYearNth = 6; - - // constants for weekdays - const olSunday = 1; - const olMonday = 2; - const olTuesday = 4; - const olWednesday = 8; - const olThursday = 16; - const olFriday = 32; - const olSaturday = 64; - - // standard headers - const xml_decl = ''; - const SIF_decl = '1.1'; - - - /** - * Constructor - * - * @param array $_clientProperties client properties - */ - function __construct(&$_clientProperties = array()) - { - parent::__construct(); - if ($this->log) $this->logfile = $GLOBALS['egw_info']['server']['temp_dir']."/log-sifcal"; - $this->clientProperties = $_clientProperties; - $this->vCalendar = new Horde_iCalendar; - } - - - function startElement($_parser, $_tag, $_attributes) - { - } - - function endElement($_parser, $_tag) - { - switch (strtolower($_tag)) - { - case 'excludedate': - $this->event['recur_exception'][] = trim($this->sifData); - break; - - default: - if(!empty($this->sifMapping[$_tag])) - { - $this->event[$this->sifMapping[$_tag]] = trim($this->sifData); - } - } - unset($this->sifData); - } - - function characterData($_parser, $_data) - { - $this->sifData .= $_data; - } - - /** - * Get DateTime value for a given time and timezone - * - * @param int|string|DateTime $time in server-time as returned by calendar_bo for $data_format='server' - * @param string $tzid TZID of event or 'UTC' or NULL for palmos timestamps in usertime - * @return mixed attribute value to set: integer timestamp if $tzid == 'UTC' otherwise Ymd\THis string IN $tzid - */ - function getDateTime($time, $tzid) - { - if (empty($tzid) || $tzid == 'UTC') - { - return $this->vCalendar->_exportDateTime(egw_time::to($time,'ts')); - } - if (!is_a($time,'DateTime')) - { - $time = new egw_time($time,egw_time::$server_timezone); - } - if (!isset(self::$tz_cache[$tzid])) - { - self::$tz_cache[$tzid] = calendar_timezones::DateTimeZone($tzid); - } - $time->setTimezone(self::$tz_cache[$tzid]); - - return $time->format('Ymd\THis'); - } - - function siftoegw($sifData, $_calID=-1) - { - $finalEvent = array(); - $this->event = array(); - $sysCharSet = $GLOBALS['egw']->translation->charset(); - - - if ($this->tzid) - { - $tzid = $this->tzid; - } - else - { - $tzid = egw_time::$user_timezone->getName(); - } - - date_default_timezone_set($tzid); - $finalEvent['tzid'] = $tzid; - - $this->xml_parser = xml_parser_create('UTF-8'); - xml_set_object($this->xml_parser, $this); - xml_parser_set_option($this->xml_parser, XML_OPTION_CASE_FOLDING, false); - xml_set_element_handler($this->xml_parser, "startElement", "endElement"); - xml_set_character_data_handler($this->xml_parser, "characterData"); - $this->strXmlData = xml_parse($this->xml_parser, $sifData); - if (!$this->strXmlData) - { - error_log(sprintf("XML error: %s at line %d", - xml_error_string(xml_get_error_code($this->xml_parser)), - xml_get_current_line_number($this->xml_parser))); - date_default_timezone_set($GLOBALS['egw_info']['server']['server_timezone']); - return false; - } - - foreach ($this->event as $key => $value) - { - $value = preg_replace('/<\!\[CDATA\[(.+)\]\]>/Usim', '$1', $value); - $value = $GLOBALS['egw']->translation->convert($value, 'utf-8', $sysCharSet); - /* - if ($this->log) - { - error_log(__FILE__.'['.__LINE__.'] '.__METHOD__. - "() $key => $value\n",3,$this->logfile); - } - */ - switch ($key) - { - case 'alldayevent': - if ($value == 1) - { - $finalEvent['whole_day'] = true; - $startParts = explode('-',$this->event['start']); - $finalEvent['startdate']['hour'] = $finalEvent['startdate']['minute'] = $finalEvent['startdate']['second'] = 0; - $finalEvent['startdate']['year'] = $startParts[0]; - $finalEvent['startdate']['month'] = $startParts[1]; - $finalEvent['startdate']['day'] = $startParts[2]; - $finalEvent['start'] = $this->date2ts($finalEvent['startdate']); - $endParts = explode('-',$this->event['end']); - $finalEvent['enddate']['hour'] = 23; $finalEvent['enddate']['minute'] = $finalEvent['enddate']['second'] = 59; - $finalEvent['enddate']['year'] = $endParts[0]; - $finalEvent['enddate']['month'] = $endParts[1]; - $finalEvent['enddate']['day'] = $endParts[2]; - $finalEvent['end'] = $this->date2ts($finalEvent['enddate']); - } - break; - - case 'public': - $finalEvent[$key] = ((int)$value > 0) ? 0 : 1; - break; - - case 'category': - if (!empty($value)) - { - $categories1 = explode(',', $value); - $categories2 = explode(';', $value); - $categories = count($categories1) > count($categories2) ? $categories1 : $categories2; - $finalEvent[$key] = $this->find_or_add_categories($categories, $_calID); - } - break; - - case 'end': - case 'start': - if ($this->event['alldayevent'] < 1) - { - $finalEvent[$key] = $this->vCalendar->_parseDateTime($value); - } - break; - - case 'isrecurring': - if ($value == 1) - { - $finalEvent['recur_exception'] = array(); - if (is_array($this->event['recur_exception'])) - { - foreach ($this->event['recur_exception'] as $day) - { - $finalEvent['recur_exception'][] = $this->vCalendar->_parseDateTime($day); - } - array_unique($finalEvent['recur_exception']); - } - $finalEvent['recur_interval'] = $this->event['recur_interval']; - $finalEvent['recur_data'] = 0; - if ($this->event['recur_noenddate'] == 0) - { - $recur_enddate = $this->vCalendar->_parseDateTime($this->event['recur_enddate']); - $finalEvent['recur_enddate'] = mktime(0, 0, 0, - date('m', $recur_enddate), - date('d', $recur_enddate), - date('Y', $recur_enddate)); - } - switch ($this->event['recur_type']) - { - case self::olRecursDaily: - $finalEvent['recur_type'] = MCAL_RECUR_DAILY; - break; - - case self::olRecursWeekly: - $finalEvent['recur_type'] = MCAL_RECUR_WEEKLY; - $finalEvent['recur_data'] = $this->event['recur_weekmask']; - break; - - case self::olRecursMonthly: - $finalEvent['recur_type'] = MCAL_RECUR_MONTHLY_MDAY; - break; - - case self::olRecursMonthNth: - $finalEvent['recur_type'] = MCAL_RECUR_MONTHLY_WDAY; - break; - - case self::olRecursYearly: - $finalEvent['recur_type'] = MCAL_RECUR_YEARLY; - $finalEvent['recur_interval'] = 1; - break; - } - } - break; - - case 'priority': - $finalEvent[$key] = $value + 1; - break; - - case 'reminderset': - if ($value == 1) - { - $finalEvent['alarm'] = $this->event['reminderstart']; - } - break; - - case 'recur_type': - case 'recur_enddate': - case 'recur_interval': - case 'recur_weekmask': - case 'reminderstart': - case 'recur_exception': - // do nothing, get's handled in isrecuring clause - break; - - case 'description': - if (preg_match('/\s*\[UID:(.+)?\]/Usm', $value, $matches)) - { - $finalEvent['uid'] = $matches[1]; - } - - default: - $finalEvent[$key] = str_replace("\r\n", "\n", $value); - break; - } - } - - if ($this->calendarOwner) $finalEvent['owner'] = $this->calendarOwner; - - date_default_timezone_set($GLOBALS['egw_info']['server']['server_timezone']); - - if ($_calID > 0) $finalEvent['id'] = $_calID; - - if ($this->log) - { - error_log(__FILE__.'['.__LINE__.'] '.__METHOD__."()\n" . - array2string($finalEvent)."\n",3,$this->logfile); - } - - return $finalEvent; - } - - function search($_sifdata, $contentID=null, $relax=false) - { - $result = array(); - $filter = $relax ? 'relax' : 'exact'; - - if ($event = $this->siftoegw($_sifdata, $contentID)) - { - if ($contentID) { - $event['id'] = $contentID; - } - $result = $this->find_event($event, $filter); - } - return $result; - } - - /** - * @return int event id - * @param string $_sifdata the SIFE data - * @param int $_calID=-1 the internal addressbook id - * @param boolean $merge=false merge data with existing entry - * @param int $recur_date=0 if set, import the recurrence at this timestamp, - * default 0 => import whole series (or events, if not recurring) - * @desc import a SIFE into the calendar - */ - function addSIF($_sifdata, $_calID=-1, $merge=false, $recur_date=0) - { - if ($this->log) - { - error_log(__FILE__.'['.__LINE__.'] '.__METHOD__."()\n" . - array2string($_sifdata)."\n",3,$this->logfile); - } - if (!$event = $this->siftoegw($_sifdata, $_calID)) - { - return false; - } - - /* - if ($event['recur_type'] != MCAL_RECUR_NONE) - { - // Adjust the event start -- no exceptions before and at the start - $length = $event['end'] - $event['start']; - $rriter = calendar_rrule::event2rrule($event, false); - $rriter->rewind(); - if (!$rriter->valid()) continue; // completely disolved into exceptions - - $newstart = egw_time::to($rriter->current, 'server'); - if ($newstart != $event['start']) - { - // leading exceptions skiped - $event['start'] = $newstart; - $event['end'] = $newstart + $length; - } - - $exceptions = $event['recur_exception']; - foreach($exceptions as $key => $day) - { - // remove leading exceptions - if ($day <= $event['start']) - { - if ($this->log) - { - error_log(__FILE__.'['.__LINE__.'] '.__METHOD__. - '(): event SERIES-MASTER skip leading exception ' . - $day . "\n",3,$this->logfile); - } - unset($exceptions[$key]); - } - } - $event['recur_exception'] = $exceptions; - } */ - - if ($recur_date) $event['recurrence'] = $recur_date; - $event_info = $this->get_event_info($event); - - // common adjustments for existing events - if (is_array($event_info['stored_event'])) - { - if (empty($event['uid'])) - { - $event['uid'] = $event_info['stored_event']['uid']; // restore the UID if it was not delivered - } - if ($merge) - { - // overwrite with server data for merge - foreach ($event_info['stored_event'] as $key => $value) - { - if ($key == 'participants') - { - unset($event[$key]); - continue; - } - if (!empty($value)) $event[$key] = $value; - } - } - else - { - // not merge - // SIF clients do not support participants => add them back - unset($event['participants']); - if (!empty($event['whole_day']) && $event['tzid'] != $event_info['stored_event']['tzid']) - { - if (!isset(self::$tz_cache[$event_info['stored_event']['tzid']])) - { - self::$tz_cache[$event_info['stored_event']['tzid']] = - calendar_timezones::DateTimeZone($event_info['stored_event']['tzid']); - } - // Adjust dates to original TZ - $time = new egw_time($event['startdate'],self::$tz_cache[$event_info['stored_event']['tzid']]); - $event['start'] = egw_time::to($time, 'server'); - $time = new egw_time($event['enddate'],self::$tz_cache[$event_info['stored_event']['tzid']]); - $event['end'] = egw_time::to($time, 'server'); - if ($event['recur_type'] != MCAL_RECUR_NONE) - { - foreach ($event['recur_exception'] as $key => $day) - { - $time = new egw_time($day,egw_time::$server_timezone); - $time =& $this->so->startOfDay($time, $event_info['stored_event']['tzid']); - $event['recur_exception'][$key] = egw_time::to($time,'server'); - } - } - } - - calendar_rrule::rrule2tz($event, $event_info['stored_event']['start'], - $event_info['stored_event']['tzid']); - - $event['tzid'] = $event_info['stored_event']['tzid']; - // avoid that iCal changes the organizer, which is not allowed - $event['owner'] = $event_info['stored_event']['owner']; - } - } - else // common adjustments for new events - { - // set non blocking all day depending on the user setting - if (!empty($event['whole_day']) && $this->nonBlockingAllday) - { - $event['non_blocking'] = 1; - } - - // check if an owner is set and the current user has add rights - // for that owners calendar; if not set the current user - if (!isset($event['owner']) - || !$this->check_perms(EGW_ACL_ADD, 0, $event['owner'])) - { - $event['owner'] = $this->user; - } - - $status = $event['owner'] == $this->user ? 'A' : 'U'; - $status = calendar_so::combine_status($status, 1, 'CHAIR'); - $event['participants'] = array($event['owner'] => $status); - } - - unset($event['startdate']); - unset($event['enddate']); - - $alarmData = array(); - if (isset($event['alarm'])) - { - $alarmData['offset'] = $event['alarm'] * 60; - $alarmData['time'] = $event['start'] - $alarmData['offset']; - $alarmData['owner'] = $this->user; - $alarmData['all'] = false; - } - - // update alarms depending on the given event type - if (!empty($alarmData) || isset($this->supportedFields['alarm'])) - { - switch ($event_info['type']) - { - case 'SINGLE': - case 'SERIES-MASTER': - case 'SERIES-EXCEPTION': - case 'SERIES-EXCEPTION-PROPAGATE': - if (isset($event['alarm'])) - { - if (is_array($event_info['stored_event']) - && count($event_info['stored_event']['alarm']) > 0) - { - foreach ($event_info['stored_event']['alarm'] as $alarm_id => $alarm_data) - { - if ($alarmData['time'] == $alarm_data['time'] && - ($alarm_data['all'] || $alarm_data['owner'] == $this->user)) - { - unset($alarmData); - unset($event_info['stored_event']['alarm'][$alarm_id]); - break; - } - } - if (isset($alarmData)&&is_array($alarmData)) $event['alarm'][] = $alarmData; - } - } - break; - - case 'SERIES-PSEUDO-EXCEPTION': - // nothing to do here - break; - } - if (is_array($event_info['stored_event']) - && count($event_info['stored_event']['alarm']) > 0) - { - foreach ($event_info['stored_event']['alarm'] as $alarm_id => $alarm_data) - { - // only touch own alarms - if ($alarm_data['all'] == false && $alarm_data['owner'] == $this->user) - { - $this->delete_alarm($alarm_id); - } - } - } - } - - // save event depending on the given event type - switch ($event_info['type']) - { - case 'SINGLE': - if ($this->log) - { - error_log(__FILE__.'['.__LINE__.'] '.__METHOD__. - "(): event SINGLE\n",3,$this->logfile); - } - - // update the event - if ($event_info['acl_edit']) - { - // Force SINGLE - unset($event['recurrence']); - $event['reference'] = 0; - $event_to_store = $event; // prevent $event from being changed by the update method - $updated_id = $this->update($event_to_store, true); - unset($event_to_store); - } - break; - - case 'SERIES-MASTER': - if ($this->log) - { - error_log(__FILE__.'['.__LINE__.'] '.__METHOD__. - "(): event SERIES-MASTER\n",3,$this->logfile); - } - - // remove all known pseudo exceptions and update the event - if ($event_info['acl_edit']) - { - $days = $this->so->get_recurrence_exceptions($event_info['stored_event'], $this->tzid, 0, 0, 'tz_map'); - if ($this->log) - { - error_log(__FILE__.'['.__LINE__.'] '.__METHOD__."(EXCEPTIONS MAPPING):\n" . - array2string($days)."\n",3,$this->logfile); - } - if (is_array($days)) - { - $exceptions = array(); - foreach ($event['recur_exception'] as $recur_exception) - { - if (isset($days[$recur_exception])) - { - $exceptions[] = $days[$recur_exception]; - } - } - $event['recur_exception'] = $exceptions; - } - - $event_to_store = $event; // prevent $event from being changed by the update method - $updated_id = $this->update($event_to_store, true); - unset($event_to_store); - } - break; - - case 'SERIES-EXCEPTION': - case 'SERIES-EXCEPTION-PROPAGATE': - if ($this->log) - { - error_log(__FILE__.'['.__LINE__.'] '.__METHOD__. - "(): event SERIES-EXCEPTION\n",3,$this->logfile); - } - - // update event - if ($event_info['acl_edit']) - { - if (isset($event_info['stored_event']['id'])) - { - // We update an existing exception - $event['id'] = $event_info['stored_event']['id']; - $event['category'] = $event_info['stored_event']['category']; - } - else - { - // We create a new exception - unset($event['id']); - unset($event_info['stored_event']); - $event['recur_type'] = MCAL_RECUR_NONE; - $event_info['master_event']['recur_exception'] = - array_unique(array_merge($event_info['master_event']['recur_exception'], - array($event['recurrence']))); - /* - // Adjust the event start -- must not be an exception - $length = $event_info['master_event']['end'] - $event_info['master_event']['start']; - $rriter = calendar_rrule::event2rrule($event_info['master_event'], false); - $rriter->rewind(); - if ($rriter->valid()) - { - $newstart = egw_time::to($rriter->current, 'server'); - foreach($event_info['master_event']['recur_exception'] as $key => $day) - { - // remove leading exceptions - if ($day < $newstart) - { - unset($event_info['master_event']['recur_exception'][$key]); - } - } - } - if ($event_info['master_event']['start'] < $newstart) - { - $event_info['master_event']['start'] = $newstart; - $event_info['master_event']['end'] = $newstart + $length; - $event_to_store = $event_info['master_event']; // prevent the master_event from being changed by the update method - $this->server2usertime($event_to_store); - $this->update($event_to_store, true); - unset($event_to_store); - } */ - $event['reference'] = $event_info['master_event']['id']; - $event['category'] = $event_info['master_event']['category']; - $event['owner'] = $event_info['master_event']['owner']; - } - - $event_to_store = $event; // prevent $event from being changed by update method - $updated_id = $this->update($event_to_store, true); - unset($event_to_store); - } - break; - - case 'SERIES-PSEUDO-EXCEPTION': - if ($this->log) - { - error_log(__FILE__.'['.__LINE__.'] '.__METHOD__. - "(): event SERIES-PSEUDO-EXCEPTION\n",3,$this->logfile); - } - - if ($event_info['acl_edit']) - { - // truncate the status only exception from the series master - $recur_exceptions = array(); - foreach ($event_info['master_event']['recur_exception'] as $recur_exception) - { - if ($recur_exception != $event['recurrence']) - { - $recur_exceptions[] = $recur_exception; - } - } - $event_info['master_event']['recur_exception'] = $recur_exceptions; - - // save the series master with the adjusted exceptions - $event_to_store = $event_info['master_event']; // prevent the master_event from being changed by the update method - $updated_id = $this->update($event_to_store, true, true, false, false); - unset($event_to_store); - } - } - - // read stored event into info array for fresh stored (new) events - if (!is_array($event_info['stored_event']) && $updated_id > 0) - { - $event_info['stored_event'] = $this->read($updated_id); - } - - // choose which id to return to the client - switch ($event_info['type']) - { - case 'SINGLE': - case 'SERIES-MASTER': - case 'SERIES-EXCEPTION': - $return_id = $updated_id; - break; - - case 'SERIES-PSEUDO-EXCEPTION': - $return_id = is_array($event_info['master_event']) ? $event_info['master_event']['id'] . ':' . $event['recurrence'] : false; - break; - - case 'SERIES-EXCEPTION-PROPAGATE': - if ($event_info['acl_edit'] && is_array($event_info['stored_event'])) - { - // we had sufficient rights to propagate the status only exception to a real one - $return_id = $event_info['stored_event']['id']; - } - else - { - // we did not have sufficient rights to propagate the status only exception to a real one - // we have to keep the SERIES-PSEUDO-EXCEPTION id and keep the event untouched - $return_id = $event_info['master_event']['id'] . ':' . $event['recurrence']; - } - break; - } - - if ($this->log) - { - $recur_date = $this->date2usertime($event_info['stored_event']['start']); - $event_info['stored_event'] = $this->read($event_info['stored_event']['id'], $recur_date); - error_log(__FILE__.'['.__LINE__.'] '.__METHOD__."()\n" . - array2string($event_info['stored_event'])."\n",3,$this->logfile); - } - - return $return_id; - } - - /** - * return a sife - * - * @param int $_id the id of the event - * @param int $recur_date=0 if set export the next recurrence at or after the timestamp, - * default 0 => export whole series (or events, if not recurring) - * @return string containing the SIFE - */ - function getSIF($_id, $recur_date=0) - { - if ($this->log) - { - error_log(__FILE__.'['.__LINE__.'] '.__METHOD__. - "($_id, $recur_date)\n",3,$this->logfile); - } - $sysCharSet = $GLOBALS['egw']->translation->charset(); - - $fields = array_unique(array_values($this->sifMapping)); - sort($fields); - $tzid = null; - - if (!($event = $this->read($_id, $recur_date, false, 'server'))) - { - if ($this->read($_id, $recur_date, true, 'server')) - { - $retval = -1; // Permission denied - if($this->xmlrpc) - { - $GLOBALS['server']->xmlrpc_error($GLOBALS['xmlrpcerr']['no_access'], - $GLOBALS['xmlrpcstr']['no_access']); - } - if ($this->log) - { - error_log(__FILE__.'['.__LINE__.'] '.__METHOD__. - "() User does not have the permission to read event $_id.\n", - 3,$this->logfile); - } - } - else - { - $retval = false; // Entry does not exist - if ($this->log) - { - error_log(__FILE__.'['.__LINE__.'] '.__METHOD__. - "() Event $_id not found.\n",3,$this->logfile); - } - } - return $retval; - } - - if ($this->log) - { - error_log(__FILE__.'['.__LINE__.'] '.__METHOD__."()\n" . - array2string($event)."\n",3,$this->logfile); - } - - if ($this->tzid) - { - // explicit device timezone - $tzid = $this->tzid; - } - elseif ($this->tzid === false) - { - // use event's timezone - $tzid = $event['tzid']; - } - - if ($this->so->isWholeDay($event)) $event['whole_day'] = true; - - if ($tzid) - { - if (!isset(self::$tz_cache[$tzid])) - { - self::$tz_cache[$tzid] = calendar_timezones::DateTimeZone($tzid); - } - } - if (!isset(self::$tz_cache[$event['tzid']])) - { - self::$tz_cache[$event['tzid']] = calendar_timezones::DateTimeZone($event['tzid']); - } - - if ($recur_date && ($master = $this->read($_id, 0, true, 'server'))) - { - $days = $this->so->get_recurrence_exceptions($master, $tzid, 0, 0, 'tz_rrule'); - if (isset($days[$recur_date])) - { - $recur_date = $days[$recur_date]; // use remote representation - } - else - { - if ($this->log) - { - error_log(__FILE__.'['.__LINE__.'] '.__METHOD__. - "($_id, $recur_date) Unsupported status only exception, skipped ...\n", - 3, $this->logfile); - } - return false; // unsupported pseudo exception - } - /* - $time = new egw_time($master['start'], egw_time::$server_timezone); - $time->setTimezone(self::$tz_cache[$tzid]); - $first_start = $time->format('His'); - $time = new egw_time($event['start'], egw_time::$server_timezone); - $time->setTimezone(self::$tz_cache[$tzid]); - $recur_start = $time->format('His'); - if ($first_start == $recur_start) return false; // Nothing to export - */ - $event['recur_type'] = MCAL_RECUR_NONE; - } - elseif (!$recur_date && - $event['recur_type'] != MCAL_RECUR_NONE && - empty($event['whole_day'])) // whole-day events are not shifted - { - // Add the timezone transition related pseudo exceptions - $exceptions = $this->so->get_recurrence_exceptions($event, $tzid, 0, 0, 'tz_rrule'); - if ($this->log) - { - error_log(__FILE__.'['.__LINE__.'] '.__METHOD__."(EXCEPTIONS)\n" . - array2string($exceptions)."\n",3,$this->logfile); - } - $event['recur_exception'] = $exceptions; - /* - // Adjust the event start -- must not be an exception - $length = $event['end'] - $event['start']; - $rriter = calendar_rrule::event2rrule($event, false, $tzid); - $rriter->rewind(); - if (!$rriter->valid()) return false; // completely disolved into exceptions - - $event['start'] = egw_time::to($rriter->current, 'server'); - $event['end'] = $event['start'] + $length; - foreach($exceptions as $key => $day) - { - // remove leading exceptions - if ($day <= $event['start']) unset($exceptions[$key]); - } - $event['recur_exception'] = $exceptions; */ - } - - if ($this->uidExtension) - { - if (!preg_match('/\[UID:.+\]/m', $event['description'])) - { - $event['description'] .= "\n[UID:" . $event['uid'] . "]"; - } - } - - $sifEvent = self::xml_decl . "" . self::SIF_decl; - - foreach ($this->sifMapping as $sifField => $egwField) - { - if (empty($egwField)) continue; - - $value = $GLOBALS['egw']->translation->convert($event[$egwField], $sysCharSet, 'utf-8'); - - switch ($sifField) - { - case 'Importance': - $value = $value-1; - $sifEvent .= "<$sifField>$value"; - break; - - case 'RecurrenceType': - case 'Interval': - case 'PatternStartDate': - case 'NoEndDate': - case 'DayOfWeekMask': - case 'PatternEndDate': - break; - - case 'IsRecurring': - if ($event['recur_type'] == MCAL_RECUR_NONE) - { - $sifEvent .= "<$sifField>0"; - break; - } - $occurrences = 0; - if ($event['recur_enddate'] == 0) - { - $sifEvent .= '1'; - } - else - { - $rriter = calendar_rrule::event2rrule($event, false, $tzid); - $rriter->rewind(); - - while ($rriter->valid()) - { - $occurrences++; - $recur_date = $rriter->current(); - if ($this->log) - { - error_log(__FILE__.'['.__LINE__.'] '.__METHOD__. - "() Client Recurrence[$occurrences] $recur_date\n", 3, $this->logfile); - } - if (!$rriter->exceptions || !in_array($recur_date->format('Ymd'),$rriter->exceptions)) - { - $recur_end = $recur_date; - } - $rriter->next_no_exception(); - } - $recurEndDate = egw_time::to($recur_end, 'server'); - $sifEvent .= '0'; - $sifEvent .= ''. self::getDateTime($recurEndDate,$tzid) .''; - } - - calendar_rrule::rrule2tz($event, $event['start'], $tzid); - - $eventInterval = ($event['recur_interval'] > 1 ? $event['recur_interval'] : 1); - - switch ($event['recur_type']) - { - - case MCAL_RECUR_DAILY: - $sifEvent .= "<$sifField>1"; - $sifEvent .= ''. self::olRecursDaily .''; - $sifEvent .= ''. $eventInterval .''; - $sifEvent .= ''. self::getDateTime($event['start'],$tzid) .''; - if ($event['recur_enddate']) - { - $sifEvent .= ''. $occurrences .''; - } - break; - - case MCAL_RECUR_WEEKLY: - $sifEvent .= "<$sifField>1"; - $sifEvent .= ''. self::olRecursWeekly .''; - $sifEvent .= ''. $eventInterval .''; - $sifEvent .= ''. self::getDateTime($event['start'],$tzid) .''; - $sifEvent .= ''. $event['recur_data'] .''; - if ($event['recur_enddate']) - { - $sifEvent .= ''. $occurrences .''; - } - break; - - case MCAL_RECUR_MONTHLY_MDAY: - $sifEvent .= "<$sifField>1"; - $sifEvent .= ''. self::olRecursMonthly .''; - $sifEvent .= ''. $eventInterval .''; - $sifEvent .= ''. self::getDateTime($event['start'],$tzid) .''; - break; - - case MCAL_RECUR_MONTHLY_WDAY: - $weekMaskMap = array('Sun' => self::olSunday, 'Mon' => self::olMonday, 'Tue' => self::olTuesday, - 'Wed' => self::olWednesday, 'Thu' => self::olThursday, 'Fri' => self::olFriday, - 'Sat' => self::olSaturday); - $sifEvent .= "<$sifField>1"; - $sifEvent .= ''. self::olRecursMonthNth .''; - $sifEvent .= ''. $eventInterval .''; - $sifEvent .= ''. self::getDateTime($event['start'],$tzid) .''; - $sifEvent .= '' . (1 + (int) ((date('d',$event['start'])-1) / 7)) . ''; - $sifEvent .= '' . $weekMaskMap[date('D',$event['start'])] . ''; - break; - - case MCAL_RECUR_YEARLY: - $sifEvent .= "<$sifField>1"; - $sifEvent .= ''. self::olRecursYearly .''; - break; - } - if (is_array($event['recur_exception'])) - { - $sifEvent .= ''; - foreach ($event['recur_exception'] as $day) - { - if (empty($event['whole_day'])) - { - if ($this->log && is_a($day,'DateTime')) - { - error_log(__FILE__.'['.__LINE__.'] '.__METHOD__. - '() exception[' . $day->getTimezone()->getName() . ']: ' . - $day->format('Ymd\THis') . "\n",3,$this->logfile); - } - $sifEvent .= '' . self::getDateTime($day,$tzid) . ''; - } - else - { - if (!is_a($day,'DateTime')) - { - $day = new egw_time($day,egw_time::$server_timezone); - $day->setTimezone(self::$tz_cache[$event['tzid']]); - } - $sifEvent .= '' . $day->format('Y-m-d') . ''; - } - } - $sifEvent .= ''; - } - break; - - case 'Sensitivity': - $value = (!$value ? '2' : '0'); - $sifEvent .= "<$sifField>$value"; - break; - - case 'Folder': - # skip currently. This is the folder where Outlook stores the contact. - #$sifEvent .= "<$sifField>/"; - break; - - case 'AllDayEvent': - case 'End': - // get's handled by Start clause - break; - - case 'Start': - if (empty($event['whole_day'])) - { - $sifEvent .= '' . self::getDateTime($event['start'],$tzid) . ''; - $sifEvent .= '' . self::getDateTime($event['end'],$tzid) . ''; - $sifEvent .= "0"; - } - else - { - // for whole-day events we use the date in event timezone - $time = new egw_time($event['start'],egw_time::$server_timezone); - $time->setTimezone(self::$tz_cache[$event['tzid']]); - $sifEvent .= '' . $time->format('Y-m-d') . ''; - $time = new egw_time($event['end'],egw_time::$server_timezone); - $time->setTimezone(self::$tz_cache[$event['tzid']]); - $sifEvent .= '' . $time->format('Y-m-d') . ''; - $sifEvent .= "1"; - } - break; - - case 'ReminderMinutesBeforeStart': - break; - - case 'ReminderSet': - if (count((array)$event['alarm']) > 0) - { - $sifEvent .= "<$sifField>1"; - foreach ($event['alarm'] as $alarmID => $alarmData) - { - $sifEvent .= ''. $alarmData['offset']/60 .''; - // lets take only the first alarm - break; - } - } - else - { - $sifEvent .= "<$sifField>0"; - } - break; - - case 'Categories': - if (!empty($value) && ($values = $this->get_categories($value))) - { - $value = implode(', ', $values); - $value = $GLOBALS['egw']->translation->convert($value, $sysCharSet, 'utf-8'); - } - else - { - break; - } - - default: - $value = @htmlspecialchars($value, ENT_NOQUOTES, 'utf-8'); - $sifEvent .= "<$sifField>$value"; - } - } - $sifEvent .= ""; - - if ($this->log) - { - error_log(__FILE__.'['.__LINE__.'] '.__METHOD__ . - "() '$this->productName','$this->productSoftwareVersion'\n",3,$this->logfile); - error_log(__FILE__.'['.__LINE__.'] '.__METHOD__ . - "()\n".array2string($sifEvent)."\n",3,$this->logfile); - } - - return $sifEvent; - } - - /** - * Set the supported fields - * - * Currently we only store name and version, manucfacturer is always Funambol - * - * @param string $_productName - * @param string $_productSoftwareVersion - */ - function setSupportedFields($_productName='', $_productSoftwareVersion='') - { - $state =& $_SESSION['SyncML.state']; - if (isset($state)) - { - $deviceInfo = $state->getClientDeviceInfo(); - } - - if (isset($deviceInfo) && is_array($deviceInfo)) - { - if (isset($deviceInfo['uidExtension']) && - $deviceInfo['uidExtension']) - { - $this->uidExtension = true; - } - if (isset($deviceInfo['nonBlockingAllday']) && - $deviceInfo['nonBlockingAllday']) - { - $this->nonBlockingAllday = true; - } - if (isset($deviceInfo['tzid']) && - $deviceInfo['tzid']) - { - switch ($deviceInfo['tzid']) - { - case -1: - $this->tzid = false; - break; - case -2: - $this->tzid = null; - break; - default: - $this->tzid = $deviceInfo['tzid']; - } - } - if (isset($GLOBALS['egw_info']['user']['preferences']['syncml']['calendar_owner'])) - { - $owner = $GLOBALS['egw_info']['user']['preferences']['syncml']['calendar_owner']; - switch ($owner) - { - case 'G': - case 'P': - case 0: - case -1: - $owner = $this->user; - break; - default: - if ((int)$owner && $this->check_perms(EGW_ACL_EDIT, 0, $owner)) - { - $this->calendarOwner = $owner; - } - } - } - } - // store product name and software version for futher usage - if ($_productName) - { - $this->productName = strtolower($_productName); - if (preg_match('/^[^\d]*(\d+\.?\d*)[\.|\d]*$/', $_productSoftwareVersion, $matches)) - { - $this->productSoftwareVersion = $matches[1]; - } - } - if ($this->log) - { - error_log(__FILE__.'['.__LINE__.'] '.__METHOD__. - '(' . $this->productName . - ', '. $this->productSoftwareVersion . ")\n",3,$this->logfile); - } - } -} diff --git a/infolog/inc/class.infolog_groupdav.inc.php b/infolog/inc/class.infolog_groupdav.inc.php index 13b580c33d..c147ac7c13 100644 --- a/infolog/inc/class.infolog_groupdav.inc.php +++ b/infolog/inc/class.infolog_groupdav.inc.php @@ -7,12 +7,10 @@ * @package infolog * @subpackage groupdav * @author Ralf Becker - * @copyright (c) 2007-13 by Ralf Becker + * @copyright (c) 2007-15 by Ralf Becker * @version $Id$ */ -require_once EGW_SERVER_ROOT.'/phpgwapi/inc/horde/lib/core.php'; - /** * EGroupware: GroupDAV access: infolog handler * @@ -66,7 +64,7 @@ class infolog_groupdav extends groupdav_handler parent::__construct($app, $groupdav); $this->bo = new infolog_bo(); - $this->vCalendar = new Horde_iCalendar; + $this->vCalendar = new Horde_Icalendar; // since 1.9.002 we allow clients to specify the URL when creating a new event, as specified by CalDAV if (version_compare($GLOBALS['egw_info']['apps']['calendar']['version'], '1.9.002', '>=')) diff --git a/infolog/inc/class.infolog_ical.inc.php b/infolog/inc/class.infolog_ical.inc.php index 186ef3fc05..8b34342157 100644 --- a/infolog/inc/class.infolog_ical.inc.php +++ b/infolog/inc/class.infolog_ical.inc.php @@ -7,13 +7,10 @@ * @author Joerg Lehrke * @author Ralf Becker * @package infolog - * @subpackage syncml * @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License * @version $Id$ */ -require_once EGW_SERVER_ROOT.'/phpgwapi/inc/horde/lib/core.php'; - /** * InfoLog: Create and parse iCal's */ @@ -112,14 +109,14 @@ class infolog_ical extends infolog_bo * Exports multiple InfoLogs * * @param array $tasks array of info_ids or task arrays - * @param string $_version='2.0' - * @param string $_method=null only set for iTip messages - * @param string $charset='UTF-8' + * @param string $_version ='2.0' + * @param string $_method =null only set for iTip messages + * @param string $charset ='UTF-8' * @return string|boolean string with vCal or false on error (eg. no permission to read the event) */ function exportVCalendar(array $tasks, $_version='2.0', $_method=null, $charset='UTF-8') { - $vcal = new Horde_iCalendar; + $vcal = new Horde_Icalendar; foreach($tasks as $task) { @@ -135,14 +132,14 @@ class infolog_ical extends infolog_bo * Exports one InfoLog tast to an iCalendar VTODO * * @param int|array $task infolog_id or infolog-tasks data - * @param string $_version='2.0' could be '1.0' too - * @param string $_method='PUBLISH' - * @param string $charset='UTF-8' encoding of the vcalendar, default UTF-8 - * @param Horde_iCalendar $vcal=null optional iCalendar object to add vtodo to + * @param string $_version ='2.0' could be '1.0' too + * @param string $_method ='PUBLISH' + * @param string $charset ='UTF-8' encoding of the vcalendar, default UTF-8 + * @param Horde_Icalendar $vcal =null optional iCalendar object to add vtodo to * * @return string|boolean string with vCal or false on error (eg. no permission to read the event) */ - function exportVTODO($task, $_version='2.0',$_method='PUBLISH', $charset='UTF-8',Horde_iCalendar $vcal=null) + function exportVTODO($task, $_version='2.0',$_method='PUBLISH', $charset='UTF-8',Horde_Icalendar $vcal=null) { if (is_array($task)) { @@ -190,7 +187,7 @@ class infolog_ical extends infolog_bo array2string($taskData)."\n",3,$this->logfile); } - if (!isset($vcal)) $vcal = new Horde_iCalendar; + if (!isset($vcal)) $vcal = new Horde_Icalendar; $vcal->setAttribute('PRODID','-//EGroupware//NONSGML EGroupware InfoLog '.$GLOBALS['egw_info']['apps']['infolog']['version'].'//'. strtoupper($GLOBALS['egw_info']['user']['preferences']['common']['lang']),array(),false); $vcal->setAttribute('VERSION',$_version,array(),false); @@ -203,7 +200,7 @@ class infolog_ical extends infolog_bo if (!calendar_timezones::add_vtimezone($vcal, $tzid)) { error_log(__METHOD__."() unknown TZID='$tzid', defaulting to user timezone '".egw_time::$user_timezone->getName()."'!"); - calendar_timezones::add_vtimezone($vcal, $tzid=egw_time::$user_timezone->getName()); + calendar_timezones::add_vtimezone($vcal, egw_time::$user_timezone->getName()); $tzid = null; } if (!isset(self::$tz_cache[$tzid])) @@ -212,7 +209,7 @@ class infolog_ical extends infolog_bo } } - $vevent = Horde_iCalendar::newComponent('VTODO',$vcal); + $vevent = Horde_Icalendar::newComponent('VTODO',$vcal); if (!isset($this->clientProperties['SUMMARY']['Size'])) { @@ -407,7 +404,7 @@ class infolog_ical extends infolog_bo if ($value[1] == ':' && ($v = unserialize($value)) !== false) $value = $v; foreach((array)$value as $compvData) { - $comp = Horde_iCalendar::newComponent(substr($name,3), $vevent); + $comp = Horde_Icalendar::newComponent(substr($name,3), $vevent); $comp->parsevCalendar($compvData,substr($name,3),'utf-8'); $vevent->addComponent($comp); } @@ -440,7 +437,7 @@ class infolog_ical extends infolog_bo * set date-time attribute to DATE or DATE-TIME depending on value * 00:00 uses DATE else DATE-TIME * - * @param Horde_iCalendar_* $vevent + * @param Horde_Icalendar_* $vevent * @param string $attr attribute name * @param int $time timestamp in server-time * @param string $tzid timezone to use for client, null for user-time, false for server-time @@ -448,7 +445,7 @@ class infolog_ical extends infolog_bo static function setDateOrTime(&$vevent, $attr, $time, $tzid) { $params = array(); - $time_in = $time; + //$time_in = $time; if ($tzid) { @@ -507,19 +504,20 @@ class infolog_ical extends infolog_bo * Import a VTODO component of an iCal * * @param string $_vcalData - * @param int $_taskID=-1 info_id, default -1 = new entry - * @param boolean $merge=false merge data with existing entry - * @param int $user=null delegate new task to this account_id, default null - * @param string $charset=null The encoding charset for $text. Defaults to + * @param int $_taskID =-1 info_id, default -1 = new entry + * @param boolean $merge =false merge data with existing entry (no longer used) + * @param int $user =null delegate new task to this account_id, default null + * @param string $charset =null The encoding charset for $text. Defaults to * utf-8 for new format, iso-8859-1 for old format. - * @param string $caldav_name=null CalDAV URL name-part for new entries - * @param array $callback_data=null array with callback and further parameters, first param is task to save + * @param string $caldav_name =null CalDAV URL name-part for new entries + * @param array $callback_data =null array with callback and further parameters, first param is task to save * signature array callback($task, $param1, ...) * @return int|boolean integer info_id or false on error */ function importVTODO(&$_vcalData, $_taskID=-1, $merge=false, $user=null, $charset=null, $caldav_name=null, array $callback_data=null) { + unset($merge); // no longer used, but required by function signature if ($this->tzid) { @@ -575,7 +573,7 @@ class infolog_ical extends infolog_bo 'info_access','info_status','info_percent','info_datecompleted', ))); // remove all iCal fields not supported by EGroupware (stored like custom fields) - foreach($old as $name => $value) + foreach(array_keys($old) as $name) { if (substr($name,0,2) == '##') unset($old[$name]); } @@ -595,8 +593,8 @@ class infolog_ical extends infolog_bo * Search a matching infolog entry for the VTODO data * * @param string $_vcalData VTODO - * @param int $contentID=null infolog_id (or null, if unkown) - * @param boolean $relax=false if true, a weaker match algorithm is used + * @param int $contentID =null infolog_id (or null, if unkown) + * @param boolean $relax =false if true, a weaker match algorithm is used * @param string $charset The encoding charset for $text. Defaults to * utf-8 for new format, iso-8859-1 for old format. * @@ -630,7 +628,7 @@ class infolog_ical extends infolog_bo * Convert VTODO into a eGW infolog entry * * @param string $_vcalData VTODO data - * @param int $_taskID=-1 infolog_id of the entry + * @param int $_taskID =-1 infolog_id of the entry * @param string $charset The encoding charset for $text. Defaults to * utf-8 for new format, iso-8859-1 for old format. * @@ -644,7 +642,7 @@ class infolog_ical extends infolog_bo array2string($_vcalData)."\n",3,$this->logfile); } - $vcal = new Horde_iCalendar; + $vcal = new Horde_Icalendar; if (!($vcal->parsevCalendar($_vcalData, 'VCALENDAR', $charset))) { if ($this->log) @@ -655,8 +653,6 @@ class infolog_ical extends infolog_bo return false; } - $version = $vcal->getAttribute('VERSION'); - if (isset($GLOBALS['egw_info']['user']['preferences']['syncml']['minimum_uid_length'])) { $minimum_uid_length = $GLOBALS['egw_info']['user']['preferences']['syncml']['minimum_uid_length']; @@ -670,7 +666,7 @@ class infolog_ical extends infolog_bo foreach ($vcal->getComponents() as $component) { - if (!is_a($component, 'Horde_iCalendar_vtodo')) + if (!is_a($component, 'Horde_Icalendar_Vtodo')) { if ($this->log) { @@ -731,6 +727,7 @@ class infolog_ical extends infolog_bo case 'DESCRIPTION': $value = str_replace("\r\n", "\n", $attribute['value']); + $matches = null; if (preg_match('/\s*\[UID:(.+)?\]/Usm', $value, $matches)) { if (!isset($taskData['info_uid']) @@ -899,7 +896,7 @@ class infolog_ical extends infolog_bo * * @param int $_noteID the infolog_id of the entry * @param string $_type content type (e.g. text/plain) - * @param string $charset='UTF-8' encoding of the vcalendar, default UTF-8 + * @param string $charset ='UTF-8' encoding of the vcalendar, default UTF-8 * * @return string|boolean VNOTE representation of the infolog entry or false on error */ @@ -923,7 +920,7 @@ class infolog_ical extends infolog_bo $note['info_cat'] = translation::convert($cats[0], translation::charset(), $charset); } - $vnote = new Horde_iCalendar_vnote(); + $vnote = new Horde_Icalendar_Vnote(); $vnote->setAttribute('PRODID','-//EGroupware//NONSGML EGroupware InfoLog '.$GLOBALS['egw_info']['apps']['infolog']['version'].'//'. strtoupper($GLOBALS['egw_info']['user']['preferences']['common']['lang'])); $vnote->setAttribute('VERSION', '1.1'); @@ -961,15 +958,15 @@ class infolog_ical extends infolog_bo $options['ENCODING'] = 'FUNAMBOL-QP'; } } - $vevent->setAttribute($field, $value, $options); + $vnote->setAttribute($field, $value, $options); } if ($note['info_startdate']) { - $vnote->setAttribute('DCREATED',$note['info_startdate']); + $vnote->setAttribute('CREATED',$note['info_startdate']); } else { - $vnote->setAttribute('DCREATED',$GLOBALS['egw']->contenthistory->getTSforAction('infolog_note',$_noteID,'add')); + $vnote->setAttribute('CREATED',$GLOBALS['egw']->contenthistory->getTSforAction('infolog_note',$_noteID,'add')); } $vnote->setAttribute('LAST-MODIFIED',$GLOBALS['egw']->contenthistory->getTSforAction('infolog_note',$_noteID,'modify')); @@ -991,8 +988,8 @@ class infolog_ical extends infolog_bo * * @param string $_vcalData * @param string $_type content type (eg.g text/plain) - * @param int $_noteID=-1 info_id, default -1 = new entry - * @param boolean $merge=false merge data with existing entry + * @param int $_noteID =-1 info_id, default -1 = new entry + * @param boolean $merge =false merge data with existing entry (no longer used) * @param string $charset The encoding charset for $text. Defaults to * utf-8 for new format, iso-8859-1 for old format. * @@ -1000,6 +997,7 @@ class infolog_ical extends infolog_bo */ function importVNOTE(&$_vcalData, $_type, $_noteID=-1, $merge=false, $charset=null) { + unset($merge); // no longer used, but required by function signature if ($this->log) { error_log(__FILE__.'['.__LINE__.'] '.__METHOD__."()\n" . @@ -1048,7 +1046,7 @@ class infolog_ical extends infolog_bo * * @param string $_data VNOTE data * @param string $_type content type (eg.g text/plain) - * @param int $_noteID=-1 infolog_id of the entry + * @param int $_noteID =-1 infolog_id of the entry * @param string $charset The encoding charset for $text. Defaults to * utf-8 for new format, iso-8859-1 for old format. * @@ -1068,9 +1066,9 @@ class infolog_ical extends infolog_bo case 'text/plain': $note = array(); $note['info_type'] = 'note'; - $txt = translation::convert($_data, $charset); - $txt = str_replace("\r\n", "\n", $txt); + $txt = str_replace("\r\n", "\n", translation::convert($_data, $charset)); + $match = null; if (preg_match('/([^\n]+)\n\n(.*)/ms', $txt, $match)) { $note['info_subject'] = $match[1]; @@ -1083,14 +1081,13 @@ class infolog_ical extends infolog_bo break; case 'text/x-vnote': - $vnote = new Horde_iCalendar; - if (!$vcal->parsevCalendar($_data, 'VCALENDAR', $charset)) return false; - $version = $vcal->getAttribute('VERSION'); + $vnote = new Horde_Icalendar; + if (!$vnote->parsevCalendar($_data, 'VCALENDAR', $charset)) return false; $components = $vnote->getComponent(); foreach ($components as $component) { - if (is_a($component, 'Horde_iCalendar_vnote')) + if (is_a($component, 'Horde_Icalendar_Vnote')) { $note = array(); $note['info_type'] = 'note'; diff --git a/infolog/inc/class.infolog_sif.inc.php b/infolog/inc/class.infolog_sif.inc.php deleted file mode 100644 index 9b090e277f..0000000000 --- a/infolog/inc/class.infolog_sif.inc.php +++ /dev/null @@ -1,668 +0,0 @@ - - * @author Joerg Lehrke - * @package infolog - * @subpackage syncml - * @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License - * @version $Id$ - */ - -require_once EGW_SERVER_ROOT.'/phpgwapi/inc/horde/lib/core.php'; - -/** - * InfoLog: Create and parse SIF - * - */ -class infolog_sif extends infolog_bo -{ - // array containing the result of the xml parser - var $_extractedSIFData; - - // array containing the current mappings(task or note) - var $_currentSIFMapping; - - var $_sifNoteMapping = array( - 'Body' => 'info_des', - 'Categories' => 'info_cat', - 'Color' => '', - 'Date' => 'info_startdate', - 'Height' => '', - 'Left' => '', - 'Subject' => 'info_subject', - 'Top' => '', - 'Width' => '', - ); - - // mappings for SIFTask to InfologTask - var $_sifTaskMapping = array( - 'ActualWork' => '', - 'BillingInformation' => '', - 'Body' => 'info_des', - 'Categories' => 'info_cat', - 'Companies' => '', - 'Complete' => 'complete', - 'DateCompleted' => 'info_datecompleted', - 'DueDate' => 'info_enddate', - 'Importance' => 'info_priority', - 'IsRecurring' => '', - 'Mileage' => '', - 'PercentComplete' => 'info_percent', - 'ReminderSet' => '', - 'ReminderTime' => '', - 'Sensitivity' => 'info_access', - 'StartDate' => 'info_startdate', - 'Status' => 'info_status', - 'Subject' => 'info_subject', - 'TeamTask' => '', - 'TotalWork' => '', - 'RecurrenceType' => '', - 'Interval' => '', - 'MonthOfYear' => '', - 'DayOfMonth' => '', - 'DayOfWeekMask' => '', - 'Instance' => '', - 'PatternStartDate' => '', - 'NoEndDate' => '', - 'PatternEndDate' => '', - 'Occurrences' => '', - ); - - // standard headers - const xml_decl = ''; - const SIF_decl = '1.1'; - - /** - * name and version of the sync-client - * - * @var string - */ - var $productName = 'mozilla plugin'; - var $productSoftwareVersion = '0.3'; - - /** - * Shall we use the UID extensions of the description field? - * - * @var boolean - */ - var $uidExtension = false; - - /** - * user preference: Use this timezone for import from and export to device - * - * @var string - */ - var $tzid = null; - - /** - * Set Logging - * - * @var boolean - */ - var $log = false; - var $logfile="/tmp/log-infolog-sif"; - - /** - * Constructor - * - */ - function __construct() - { - parent::__construct(); - if ($this->log) $this->logfile = $GLOBALS['egw_info']['server']['temp_dir']."/log-infolog-sif"; - $this->vCalendar = new Horde_iCalendar; - } - - /** - * Get DateTime value for a given time and timezone - * - * @param int|string|DateTime $time in server-time as returned by calendar_bo for $data_format='server' - * @param string $tzid TZID of event or 'UTC' or NULL for palmos timestamps in usertime - * - */ - function getDateTime($time, $tzid) - { - if (empty($tzid) || $tzid == 'UTC') - { - return $this->vCalendar->_exportDateTime(egw_time::to($time,'ts')); - } - if (!is_a($time,'DateTime')) - { - $time = new egw_time($time,egw_time::$server_timezone); - } - if (!isset(self::$tz_cache[$tzid])) - { - self::$tz_cache[$tzid] = calendar_timezones::DateTimeZone($tzid); - } - // check for date --> export it as such - if ($time->format('Hi') == '0000') - { - $arr = egw_time::to($time, 'array'); - $time = new egw_time($arr, self::$tz_cache[$tzid]); - $value = $time->format('Y-m-d'); - } - else - { - $time->setTimezone(self::$tz_cache[$tzid]); - $value = $time->format('Ymd\THis'); - } - return $value; - } - - function startElement($_parser, $_tag, $_attributes) - { - // nothing to do - } - - function endElement($_parser, $_tag) - { - #error_log("infolog: tag=$_tag data=".trim($this->sifData)); - if (!empty($this->_currentSIFMapping[$_tag])) - { - $this->_extractedSIFData[$this->_currentSIFMapping[$_tag]] = trim($this->sifData); - } - unset($this->sifData); - } - - function characterData($_parser, $_data) - { - $this->sifData .= $_data; - } - - /** - * Convert SIF data into a eGW infolog entry - * - * @param string $sifData the SIF data - * @param string $_sifType type (note/task) - * @param int $_id=-1 the infolog id - * @return array infolog entry or false on error - */ - function siftoegw($sifData, $_sifType, $_id=-1) - { - - if ($this->log) - { - error_log(__FILE__.'['.__LINE__.'] '.__METHOD__."($_sifType, $_id)\n" . - array2string($sifData) . "\n", 3, $this->logfile); - } - - $sysCharSet = $GLOBALS['egw']->translation->charset(); - - switch ($_sifType) - { - case 'note': - $this->_currentSIFMapping = $this->_sifNoteMapping; - break; - - case 'task': - $this->_currentSIFMapping = $this->_sifTaskMapping; - break; - - default: - // we don't know how to handle this - return false; - } - - $this->xml_parser = xml_parser_create('UTF-8'); - xml_set_object($this->xml_parser, $this); - xml_parser_set_option($this->xml_parser, XML_OPTION_CASE_FOLDING, false); - xml_set_element_handler($this->xml_parser, "startElement", "endElement"); - xml_set_character_data_handler($this->xml_parser, "characterData"); - $this->strXmlData = xml_parse($this->xml_parser, $sifData); - - if (!$this->strXmlData) - { - error_log(sprintf("XML error: %s at line %d", - xml_error_string(xml_get_error_code($this->xml_parser)), - xml_get_current_line_number($this->xml_parser))); - return false; - } - - if (!array($this->_extractedSIFData)) - { - if ($this->log) - { - error_log(__FILE__.'['.__LINE__.'] '.__METHOD__."()[PARSER FAILD]\n", - 3, $this->logfile); - } - return false; - } - $infoData = array(); - - switch ($_sifType) - { - case 'task': - $infoData['info_type'] = 'task'; - $infoData['info_status'] = 'not-started'; - - if (isset($GLOBALS['egw_info']['user']['preferences']['syncml']['minimum_uid_length'])) - { - $minimum_uid_length = $GLOBALS['egw_info']['user']['preferences']['syncml']['minimum_uid_length']; - } - else - { - $minimum_uid_length = 8; - } - - foreach ($this->_extractedSIFData as $key => $value) - { - $value = preg_replace('/<\!\[CDATA\[(.+)\]\]>/Usim', '$1', $value); - $value = $GLOBALS['egw']->translation->convert($value, 'utf-8', $sysCharSet); - #error_log("infolog key=$key => value=$value"); - if (empty($value)) continue; - - switch($key) - { - case 'info_access': - $infoData[$key] = ((int)$value > 0) ? 'private' : 'public'; - break; - - case 'info_datecompleted': - case 'info_enddate': - case 'info_startdate': - if (!empty($value)) - { - $infoData[$key] = $this->vCalendar->_parseDateTime($value); - // somehow the client always deliver a timestamp about 3538 seconds, when no startdate set. - if ($infoData[$key] < 10000) unset($infoData[$key]); - } - break; - - - case 'info_cat': - if (!empty($value)) - { - $categories = $this->find_or_add_categories(explode(';', $value), $_id); - $infoData['info_cat'] = $categories[0]; - } - break; - - case 'info_priority': - $infoData[$key] = (int)$value; - break; - - case 'info_status': - switch ($value) - { - case '0': - $infoData[$key] = 'not-started'; - break; - case '1': - $infoData[$key] = 'ongoing'; - break; - case '2': - $infoData[$key] = 'done'; - $infoData['info_percent'] = 100; - break; - case '3': - $infoData[$key] = 'waiting'; - break; - case '4': - if ($this->productName == 'blackberry plug-in') - { - $infoData[$key] = 'deferred'; - } - else - { - $infoData[$key] = 'cancelled'; - } - break; - default: - $infoData[$key] = 'ongoing'; - } - break; - - case 'complete': - $infoData['info_status'] = 'done'; - $infoData['info_percent'] = 100; - break; - - case 'info_des': - // extract our UID and PARENT_UID information - if (preg_match('/\s*\[UID:(.+)?\]/Usm', $value, $matches)) - { - if (strlen($matches[1]) >= $minimum_uid_length) - { - $infoData['info_uid'] = $matches[1]; - } - //$value = str_replace($matches[0], '', $value); - } - if (preg_match('/\s*\[PARENT_UID:(.+)?\]/Usm', $value, $matches)) - { - if (strlen($matches[1]) >= $minimum_uid_length) - { - $infoData['info_id_parent'] = $this->getParentID($matches[1]); - } - //$value = str_replace($matches[0], '', $value); - } - - default: - $infoData[$key] = str_replace("\r\n", "\n", $value); - } - if ($this->log) - { - error_log(__FILE__.'['.__LINE__.'] '.__METHOD__."()\n" . - "key=$key => value=" . $infoData[$key] . "\n", 3, $this->logfile); - } - } - if (empty($infoData['info_datecompleted'])) - { - $infoData['info_datecompleted'] = 0; - } - break; - - case 'note': - $infoData['info_type'] = 'note'; - - foreach ($this->_extractedSIFData as $key => $value) - { - $value = preg_replace('/<\!\[CDATA\[(.+)\]\]>/Usim', '$1', $value); - $value = $GLOBALS['egw']->translation->convert($value, 'utf-8', $sysCharSet); - - #error_log("infolog client key=$key => value=" . $value); - switch ($key) - { - case 'info_startdate': - if (!empty($value)) - { - $infoData[$key] = $this->vCalendar->_parseDateTime($value); - // somehow the client always deliver a timestamp about 3538 seconds, when no startdate set. - if ($infoData[$key] < 10000) $infoData[$key] = ''; - } - else - { - $infoData[$key] = ''; - } - break; - - case 'info_cat': - if (!empty($value)) - { - $categories = $this->find_or_add_categories(explode(';', $value), $_id); - $infoData['info_cat'] = $categories[0]; - } - break; - - default: - $infoData[$key] = str_replace("\r\n", "\n", $value); - } - if ($this->log) - { - error_log(__FILE__.'['.__LINE__.'] '.__METHOD__."()\n" . - "key=$key => value=" . $infoData[$key] . "\n", 3, $this->logfile); - } - } - } - if ($this->log) - { - error_log(__FILE__.'['.__LINE__.'] '.__METHOD__."()\n" . - array2string($infoData) . "\n", 3, $this->logfile); - } - return $infoData; - } - - /** - * Search for SIF data a matching infolog entry - * - * @param string $sifData the SIF data - * @param string $_sifType type (note/task) - * @param int $contentID=null infolog_id (or null, if unkown) - * @param boolean $relax=false if true, a weaker match algorithm is used - * @return infolog_id of a matching entry or false, if nothing was found - */ - function searchSIF($_sifData, $_sifType, $contentID=null, $relax=false) - { - if (!($egwData = $this->siftoegw($_sifData, $_sifType, $contentID))) return array(); - - if ($contentID) $egwData['info_id'] = $contentID; - - if ($_sifType == 'note') unset($egwData['info_startdate']); - - return $this->findInfo($egwData, $relax, $this->tzid); - } - - /** - * Add SIF data entry - * - * @param string $sifData the SIF data - * @param string $_sifType type (note/task) - * @param boolean $merge=false reserved for future use - * @return infolog_id of the new entry or false, for errors - */ - function addSIF($_sifData, $_id, $_sifType, $merge=false) - { - if ($this->tzid) - { - date_default_timezone_set($this->tzid); - } - $egwData = $this->siftoegw($_sifData, $_sifType, $_id); - if ($this->tzid) - { - date_default_timezone_set($GLOBALS['egw_info']['server']['server_timezone']); - } - if (!$egwData) return false; - - if ($_id > 0) $egwData['info_id'] = $_id; - - return $this->write($egwData, true, true, false); - } - - - /** - * Export an infolog entry as SIF data - * - * @param int $_id the infolog_id of the entry - * @param string $_sifType type (note/task) - * @return string SIF representation of the infolog entry - */ - function getSIF($_id, $_sifType) - { - $sysCharSet = $GLOBALS['egw']->translation->charset(); - - if (!($infoData = $this->read($_id, true, 'server'))) return false; - - switch($_sifType) - { - case 'task': - if ($infoData['info_id_parent']) - { - $parent = $this->read($infoData['info_id_parent']); - $infoData['info_id_parent'] = $parent['info_uid']; - } - else - { - $infoData['info_id_parent'] = ''; - } - - if (!preg_match('/\[UID:.+\]/m', $infoData['info_des'])) - { - $infoData['info_des'] .= "\r\n[UID:" . $infoData['info_uid'] . "]"; - if ($infoData['info_id_parent'] != '') - { - $infoData['info_des'] .= "\r\n[PARENT_UID:" . $infoData['info_id_parent'] . "]"; - } - } - - $sifTask = self::xml_decl . "\n" . self::SIF_decl; - - foreach ($this->_sifTaskMapping as $sifField => $egwField) - { - if (empty($egwField)) continue; - - $value = $GLOBALS['egw']->translation->convert($infoData[$egwField], $sysCharSet, 'utf-8'); - - switch ($sifField) - { - - case 'Complete': - // is handled with DateCompleted - break; - - case 'DateCompleted': - if ($infoData[info_status] != 'done') - { - $sifTask .= "0"; - continue; - } - $sifTask .= "1"; - - case 'DueDate': - case 'StartDate': - $sifTask .= "<$sifField>"; - if (!empty($value)) - { - $sifTask .= $this->getDateTime($value, $this->tzid); - } - $sifTask .= ""; - break; - - case 'Importance': - if ($value > 3) $value = 3; - $sifTask .= "<$sifField>$value"; - break; - - case 'Sensitivity': - $value = ($value == 'private' ? '2' : '0'); - $sifTask .= "<$sifField>$value"; - break; - - case 'Status': - switch ($value) - { - case 'cancelled': - case 'deferred': - $value = '4'; - break; - case 'waiting': - case 'nonactive': - $value = '3'; - break; - case 'done': - case 'archive': - case 'billed': - $value = '2'; - break; - case 'not-started': - case 'template': - $value = '0'; - break; - default: //ongoing - $value = 1; - break; - } - $sifTask .= "<$sifField>$value"; - break; - - case 'Categories': - if (!empty($value) && $value) - { - $value = implode('; ', $this->get_categories(array($value))); - $value = $GLOBALS['egw']->translation->convert($value, $sysCharSet, 'utf-8'); - } - else - { - break; - } - - default: - $value = @htmlspecialchars($value, ENT_NOQUOTES, 'utf-8'); - $sifTask .= "<$sifField>$value"; - break; - } - } - $sifTask .= '00'; - return $sifTask; - - case 'note': - $sifNote = self::xml_decl . "\n" . self::SIF_decl; - - foreach ($this->_sifNoteMapping as $sifField => $egwField) - { - if(empty($egwField)) continue; - - $value = $GLOBALS['egw']->translation->convert($infoData[$egwField], $sysCharSet, 'utf-8'); - - switch ($sifField) - { - case 'Date': - $sifNote .= "<$sifField>"; - if (!empty($value)) - { - $sifNote .= $this->getDateTime($value, $this->tzid); - } - $sifNote .= ""; - break; - - case 'Categories': - if (!empty($value)) - { - $value = implode('; ', $this->get_categories(array($value))); - $value = $GLOBALS['egw']->translation->convert($value, $sysCharSet, 'utf-8'); - } - else - { - break; - } - - default: - $value = @htmlspecialchars($value, ENT_QUOTES, 'utf-8'); - $sifNote .= "<$sifField>$value"; - break; - } - } - $sifNote .= ''; - return $sifNote; - } - return false; - } - - /** - * Set the supported fields - * - * Currently we only store name and version, manucfacturer is always Funambol - * - * @param string $_productName - * @param string $_productSoftwareVersion - */ - function setSupportedFields($_productName='', $_productSoftwareVersion='') - { - $state = &$_SESSION['SyncML.state']; - $deviceInfo = $state->getClientDeviceInfo(); - - if (isset($deviceInfo) && is_array($deviceInfo)) - { - if (isset($deviceInfo['uidExtension']) && - $deviceInfo['uidExtension']) - { - $this->uidExtension = true; - } - if (isset($deviceInfo['tzid']) && - $deviceInfo['tzid']) - { - switch ($deviceInfo['tzid']) - { - case -1: - $this->tzid = false; - break; - case -2: - $this->tzid = null; - break; - default: - $this->tzid = $deviceInfo['tzid']; - } - } - } - // store product name and version, to be able to use it elsewhere - if ($_productName) - { - $this->productName = strtolower($_productName); - if (preg_match('/^[^\d]*(\d+\.?\d*)[\.|\d]*$/', $_productSoftwareVersion, $matches)) - { - $this->productSoftwareVersion = $matches[1]; - } - } - } -} diff --git a/phpgwapi/inc/horde/Horde.php b/phpgwapi/inc/horde/Horde.php deleted file mode 100644 index eebf5afb17..0000000000 --- a/phpgwapi/inc/horde/Horde.php +++ /dev/null @@ -1,1474 +0,0 @@ - - * Copyright 1999-2005 Jon Parise - * - * 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 - * @author Jon Parise - * @since Horde 1.3 - * @package Horde_Framework - */ -class Horde { - - /** - * Logs a message to the global Horde log backend. - * - * @access public - * - * @param mixed $message Either a string or a PEAR_Error object. - * @param string $file What file was the log function called from - * (e.g. __FILE__)? - * @param integer $line What line was the log function called from - * (e.g. __LINE__)? - * @param integer $priority The priority of the message. One of: - *
-     * PEAR_LOG_EMERG
-     * PEAR_LOG_ALERT
-     * PEAR_LOG_CRIT
-     * PEAR_LOG_ERR
-     * PEAR_LOG_WARNING
-     * PEAR_LOG_NOTICE
-     * PEAR_LOG_INFO
-     * PEAR_LOG_DEBUG
-     * 
- */ - function logMessage($message, $file, $line, $priority = PEAR_LOG_INFO) - { - global $conf; - - if (!$conf['log']['enabled']) { - return; - } - - if ($priority > $conf['log']['priority']) { - return; - } - - $logger = &Horde::getLogger(); - if (!is_a($logger, 'Log')) { - Horde::fatal(PEAR::raiseError('An error has occurred. Furthermore, Horde encountered an error attempting to log this error. Please check your Horde logging configuration in horde/config/conf.php.'), __FILE__, __LINE__, false); - } - - if (is_a($message, 'PEAR_Error')) { - $userinfo = $message->getUserInfo(); - $message = $message->getMessage(); - if (!empty($userinfo)) { - if (is_array($userinfo)) { - $userinfo = implode(', ', $userinfo); - } - $message .= ': ' . $userinfo; - } - } elseif (is_callable(array($message, 'getMessage'))) { - $message = $message->getMessage(); - } - - $app = isset($GLOBALS['registry']) ? $GLOBALS['registry']->getApp() : 'horde'; - $message = '[' . $app . '] ' . $message . ' [on line ' . $line . ' of "' . $file . '"]'; - - /* Make sure to log in the system's locale. */ - $locale = setlocale(LC_TIME, 0); - setlocale(LC_TIME, 'C'); - - $logger->log($message, $priority); - - /* Restore original locale. */ - setlocale(LC_TIME, $locale); - - return true; - } - - function &getLogger() - { - global $conf; - - if (empty($conf['log']['enabled'])) { - return false; - } - - static $logcheck; - if (!isset($logcheck)) { - // Try to make sure that we can log messages somehow. - if (empty($conf['log']) || - empty($conf['log']['type']) || - empty($conf['log']['name']) || - empty($conf['log']['ident']) || - !isset($conf['log']['params'])) { - Horde::fatal(PEAR::raiseError('Horde is not correctly configured to log error messages. You must configure at least a text file log in horde/config/conf.php.'), __FILE__, __LINE__, false); - } - $logcheck = true; - } - - return $logger = &Log::singleton($conf['log']['type'], $conf['log']['name'], - $conf['log']['ident'], $conf['log']['params']); - } - - /** - * Destroys any existing session on login and make sure to use a new - * session ID, to avoid session fixation issues. Should be called before - * checking a login. - * - * @access public - */ - function getCleanSession() - { - // Make sure to force a completely new session ID and clear - // all session data. - if (version_compare(phpversion(), '4.3.3') !== -1) { - session_regenerate_id(); - session_unset(); - } else { - @session_destroy(); - if (Util::extensionExists('posix')) { - $new_session_id = md5(microtime() . posix_getpid()); - } else { - $new_session_id = md5(uniqid(mt_rand(), true)); - } - session_id($new_session_id); - - // Restart the session, including setting up the session - // handler. - Horde::setupSessionHandler(); - @session_start(); - } - } - - /** - * Aborts with a fatal error, displaying debug information to the user. - * - * @access public - * - * @param mixed $error A PEAR_Error object with debug information or an - * error message. - * @param integer $file The file in which the error occured. - * @param integer $line The line on which the error occured. - * @param boolean $log Log this message via Horde::logMesage()? - */ - function fatal($error, $file, $line, $log = true) - { - @include_once 'Horde/Auth.php'; - @include_once 'Horde/CLI.php'; - - $admin = class_exists('Auth') && Auth::isAdmin(); - $cli = class_exists('Horde_CLI') && Horde_CLI::runningFromCLI(); - - $errortext = '

' . _("A fatal error has occurred") . '

'; - if (is_a($error, 'PEAR_Error')) { - $info = array_merge(array('file' => 'conf.php', 'variable' => '$conf'), - array($error->getUserInfo())); - - switch ($error->getCode()) { - case HORDE_ERROR_DRIVER_CONFIG_MISSING: - $message = sprintf(_("No configuration information specified for %s."), $info['name']) . '
' . - sprintf(_("The file %s should contain some %s settings."), - $GLOBALS['registry']->get('fileroot') . '/config/' . $info['file'], - sprintf("%s['%s']['params']", $info['variable'], $info['driver'])); - break; - - case HORDE_ERROR_DRIVER_CONFIG: - $message = sprintf(_("Required '%s' not specified in %s configuration."), $info['field'], $info['name']) . '
' . - sprintf(_("The file %s should contain a %s setting."), - $GLOBALS['registry']->get('fileroot') . '/config/' . $info['file'], - sprintf("%s['%s']['params']['%s']", $info['variable'], $info['driver'], $info['field'])); - break; - - default: - $message = $error->getMessage(); - break; - } - - $errortext .= '

' . htmlspecialchars($message) . '

'; - } elseif (is_object($error) && method_exists($error, 'getMessage')) { - $errortext .= '

' . htmlspecialchars($error->getMessage()) . '

'; - } elseif (is_string($error)) { - $errortext .= '

' . $error . '

'; - } - - if ($admin) { - $errortext .= '

' . sprintf(_("[line %s of %s]"), $line, $file) . '

'; - if (is_object($error)) { - $errortext .= '

' . _("Details (also in Horde's logfile):") . '

'; - $errortext .= '

' . htmlspecialchars(Util::bufferOutput('var_dump', $error)) . '

'; - } - } elseif ($log) { - $errortext .= '

' . _("Details have been logged for the administrator.") . '

'; - } - - // Log the error via Horde::logMessage() if requested. - if ($log) { - Horde::logMessage($error, $file, $line, PEAR_LOG_EMERG); - } - - if ($cli) { - echo strip_tags(str_replace(array('
', '

', '

', '

', '

', '

', '

'), "\n", $errortext)); - } else { - echo <<< HTML - -Horde :: Fatal Error -$errortext - -HTML; - } - exit; - } - - /** - * Adds the javascript code to the output (if output has already started) - * or to the list of script files to include via includeScriptFiles(). - * - * @access public - * - * @param string $file The full javascript file name. - * @param string $app The application name. Defaults to the current - * application. - * @param boolean $direct Include the file directly without passing it - * through javascript.php? - */ - function addScriptFile($file, $app = null, $direct = false) - { - global $registry; - static $included = array(); - - if (empty($app)) { - $app = $registry->getApp(); - } - - // Don't include scripts multiple times. - if (!empty($included[$app][$file])) { - return; - } - $included[$app][$file] = true; - - if (ob_get_length() || headers_sent()) { - if ($direct) { - $url = Horde::url($file{0} == '/' ? $registry->get('webroot', $app) . $file : $registry->get('jsuri', $app) . '/' . $file); - } else { - $url = Horde::url($registry->get('webroot', 'horde') . '/services/javascript.php'); - $url = Util::addParameter($url, array('file' => $file, - 'app' => $app)); - } - echo ''; - } else { - global $_horde_script_files; - $_horde_script_files[$app][] = array($file, $direct); - } - } - - /** - * Includes javascript files that were needed before any headers were sent. - * - * @access public - */ - function includeScriptFiles() - { - global $_horde_script_files, $registry; - - if (!empty($_horde_script_files)) { - $base_url = Horde::url($registry->get('webroot', 'horde') . '/services/javascript.php'); - foreach ($_horde_script_files as $app => $files) { - foreach ($files as $file) { - if (!empty($file[1])) { - $url = $file[0]{0} == '/' ? $registry->get('webroot', $app) . $file[0] : $registry->get('jsuri', $app) . '/' . $file[0]; - echo '\n"; - } else { - $url = Util::addParameter($base_url, array('file' => $file[0], - 'app' => $app)); - echo '\n"; - } - } - } - } - } - - /** - * Includes javascript files that were needed before any headers were sent. - * - * @access public - */ - function inlineScriptFiles() - { - global $_horde_script_files, $registry; - - if (!empty($_horde_script_files)) { - $jsWrapper = $registry->get('fileroot', 'horde') . '/services/javascript.php'; - foreach ($_horde_script_files as $app => $files) { - foreach ($files as $file) { - if (!empty($file[1])) { - @readfile($file[0]{0} == '/' ? $registry->get('fileroot', $app) . $file[0] : $registry->get('jsfs', $app) . '/' . $file[0]); - } else { - $file = $file[0]; - require $jsWrapper; - } - } - } - } - } - - /** - * Checks if link should be shown and return the nescessary code. - * - * @access public - * - * @param string $type Type of link to display - * @param string $app The name of the current Horde application. - * @param boolean $override Override Horde settings? - * @param boolean $referrer Include the current page as the referrer (url=)? - * - * @return string The HTML to create the link. - */ - function getServiceLink($type, $app, $override = false, $referrer = true) - { - if (!Horde::showService($type) && !$override) { - return false; - } - - switch ($type) { - case 'help': - if ($GLOBALS['browser']->hasFeature('javascript')) { - Horde::addScriptFile('open_help_win.js', 'horde'); - return "javascript:open_help_win('$app');"; - } else { - $url = Horde::url($GLOBALS['registry']->get('webroot', 'horde') . '/services/help/', true); - return Util::addParameter($url, array('module' => $app, - 'show' => 'topics')); - } - break; - - case 'problem': - return Horde::url($GLOBALS['registry']->get('webroot', 'horde') . '/services/problem.php?return_url=' . urlencode(Horde::selfUrl(true))); - - case 'logout': - return Auth::addLogoutParameters(Horde::url($GLOBALS['registry']->get('webroot', 'horde') . '/login.php'), AUTH_REASON_LOGOUT); - - case 'login': - return Auth::getLoginScreen('', $referrer ? Horde::selfUrl(true) : null); - - case 'options': - global $conf; - if (($conf['prefs']['driver'] != '') && ($conf['prefs']['driver'] != 'none')) { - return Horde::url($GLOBALS['registry']->get('webroot', 'horde') . '/services/prefs.php?app=' . $app); - } - break; - } - - return false; - } - - /** - * @access public - * - * @param string $type The type of link. - * - * @return boolean True if the link is to be shown. - */ - function showService($type) - { - global $conf; - - if (empty($conf['menu']['links'][$type])) { - return false; - } - - switch ($conf['menu']['links'][$type]) { - case 'all': - return true; - - case 'never': - return false; - - case 'authenticated': - return (bool)Auth::getAuth(); - - default: - return false; - } - } - - /** - * Returns the driver parameters for the specified backend. - * - * @param mixed $backend The backend system (e.g. 'prefs', 'categories', - * 'contacts') being used. - * The used configuration array will be - * $conf[$backend]. If an array gets passed, it will - * be $conf[$key1][$key2]. - * @param string $type The type of driver. - * - * @return array The connection parameters. - */ - function getDriverConfig($backend, $type = 'sql') - { - global $conf; - - $c = null; - if (is_array($backend)) { - require_once 'Horde/Array.php'; - $c = Horde_Array::getElement($conf, $backend); - } elseif (isset($conf[$backend])) { - $c = $conf[$backend]; - } - if (!is_null($c) && isset($c['params'])) { - if (isset($conf[$type])) { - return array_merge($conf[$type], $c['params']); - } else { - return $c['params']; - } - } - - return isset($conf[$type]) ? $conf[$type] : array(); - } - - - /** - * Returns the VFS driver parameters for the specified backend. - * - * @param string $name The VFS system name (e.g. 'images', 'documents') - * being used. - * - * @return array A hash with the VFS parameters; the VFS driver in 'type' - * and the connection parameters in 'params'. - */ - function getVFSConfig($name) - { - global $conf; - - if (!isset($conf[$name]['type'])) { - return PEAR::raiseError(_("You must configure a VFS backend.")); - } - - if ($conf[$name]['type'] == 'horde') { - $vfs = $conf['vfs']; - } else { - $vfs = $conf[$name]; - } - - if ($vfs['type'] == 'sql') { - $vfs['params'] = Horde::getDriverConfig($name, 'sql'); - } - - return $vfs; - } - - /** - * Checks if all necessary parameters for a driver configuration - * are set and throws a fatal error with a detailed explaination - * how to fix this, if something is missing. - * - * @param array $params The configuration array with all parameters. - * @param string $driver The key name (in the configuration array) of - * the driver. - * @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 string $file The configuration file that should contain - * these settings. - * @param string $variable The name of the configuration variable. - */ - function assertDriverConfig($params, $driver, $fields, $name = null, - $file = 'conf.php', $variable = '$conf') - { - global $registry; - - // Don't generate a fatal error if we fail during or before - // Registry instantiation. - if (is_null($name)) { - $name = isset($registry) ? $registry->getApp() : '[unknown]'; - } - $fileroot = isset($registry) ? $registry->get('fileroot') : ''; - - if (!is_array($params) || !count($params)) { - Horde::fatal(PEAR::raiseError( - sprintf(_("No configuration information specified for %s."), $name) . "\n\n" . - sprintf(_("The file %s should contain some %s settings."), - $fileroot . '/config/' . $file, - sprintf("%s['%s']['params']", $variable, $driver))), - __FILE__, __LINE__); - } - - foreach ($fields as $field) { - if (!isset($params[$field])) { - Horde::fatal(PEAR::raiseError( - sprintf(_("Required '%s' not specified in %s configuration."), $field, $name) . "\n\n" . - sprintf(_("The file %s should contain a %s setting."), - $fileroot . '/config/' . $file, - sprintf("%s['%s']['params']['%s']", $variable, $driver, $field))), - __FILE__, __LINE__); - } - } - } - - /** - * Returns a session-id-ified version of $uri. - * If a full URL is requested, all parameter separators get converted to - * "&", otherwise to "&". - * - * @access public - * - * @param string $uri The URI to be modified. - * @param bool $full Generate a full (http://server/path/) URL. - * @param int $append_session 0 = only if needed, 1 = always, -1 = never. - * - * @return string The URL with the session id appended (if needed). - */ - function url($uri, $full = false, $append_session = 0, $force_ssl = false) - { - if ($force_ssl) { - $full = true; - } - - if ($full) { - global $conf, $registry, $browser; - - /* Store connection parameters in local variables. */ - $server_name = $conf['server']['name']; - $server_port = $conf['server']['port']; - - $protocol = 'http'; - if ($conf['use_ssl'] == 1) { - $protocol = 'https'; - } elseif ($conf['use_ssl'] == 2 && - $browser->usingSSLConnection()) { - $protocol = 'https'; - } elseif ($conf['use_ssl'] == 3) { - $server_port = ''; - if ($force_ssl) { - $protocol = 'https'; - } - } - - /* If using non-standard ports, add the port to the URL. */ - if (!empty($server_port) && - ((($protocol == 'http') && ($server_port != 80)) || - (($protocol == 'https') && ($server_port != 443)))) { - $server_name .= ':' . $server_port; - } - - /* Store the webroot in a local variable. */ - $webroot = $registry->get('webroot'); - - $url = $protocol . '://' . $server_name; - if (substr($uri, 0, 1) != '/') { - if (substr($webroot, -1) == '/') { - $url .= $webroot . $uri; - } else { - $url .= $webroot . '/' . $uri; - } - } else { - $url .= $uri; - } - } else { - $url = $uri; - } - - if (($append_session == 1) || - (($append_session == 0) && - !isset($_COOKIE[session_name()]))) { - $url = Util::addParameter($url, session_name(), session_id()); - } - - if ($full) { - /* We need to run the replace twice, because we only catch every - * second match. */ - return preg_replace(array('/(=?.*?)&(.*?=)/', - '/(=?.*?)&(.*?=)/'), - '$1&$2', $url); - } elseif (preg_match('/=.*&.*=/', $url)) { - return $url; - } else { - return htmlentities($url); - } - } - - /** - * Returns a session-id-ified version of $uri, using the current - * application's webroot setting. - * - * @access public - * - * @param string $uri The URI to be modified. - * @param bool $full Generate a full (http://server/path/) URL. - * @param int $append_session 0 = only if needed, 1 = always, -1 = never. - * - * @return string The url with the session id appended. - */ - function applicationUrl($uri, $full = false, $append_session = 0) - { - global $registry; - - /* Store the webroot in a local variable. */ - $webroot = $registry->get('webroot'); - - if ($full) { - return Horde::url($uri, $full, $append_session); - } elseif (substr($webroot, -1) == '/') { - return Horde::url($webroot . $uri, $full, $append_session); - } else { - return Horde::url($webroot . '/' . $uri, $full, $append_session); - } - } - - /** - * Returns an external link passed through the dereferer to strip session - * IDs from the referer. - * - * @param string $url The external URL to link to. - * @param boolean $tag If true, a complete tag is returned, only the - * url otherwise. - * - * @return string The correct link to the dereferer script. - */ - function externalUrl($url, $tag = false) - { - $ext = Horde::url($GLOBALS['registry']->get('webroot', 'horde') . - '/services/go.php', true, -1); - - /* We must make sure there are no &'s in the URL. */ - $url = preg_replace(array('/(=?.*?)&(.*?=)/', '/(=?.*?)&(.*?=)/'), '$1&$2', $url); - $ext = Util::addParameter($ext, 'url', $url); - if ($tag) { - $ext = Horde::link($ext, $url, '', '_blank'); - } - return $ext; - } - - /** - * Returns a URL to be used for downloading, that takes into account any - * special browser quirks (i.e. IE's broken filename handling). - * - * @access public - * - * @param string $filename The filename of the download data. - * @param array $params Any additional parameters needed. - * @param string $url The URL to alter. If none passed in, will use - * the file 'view.php' located in the current - * module's base directory. - * - * @return string The download URL. - */ - function downloadUrl($filename, $params = array(), $url = null) - { - global $browser; - - $horde_url = false; - - if (is_null($url)) { - global $registry; - $url = Util::addParameter(Horde::url($registry->get('webroot', 'horde') . '/services/download/'), 'module', $registry->getApp()); - $horde_url = true; - } - - /* Add parameters. */ - if (!is_null($params)) { - foreach ($params as $key => $val) { - $url = Util::addParameter($url, $key, $val); - } - } - - /* If we are using the default Horde download link, add the - * filename to the end of the URL. Although not necessary for - * many browsers, this should allow every browser to download - * correctly. */ - if ($horde_url) { - $url = Util::addParameter($url, 'fn=/' . rawurlencode($filename)); - } elseif ($browser->hasQuirk('break_disposition_filename')) { - /* Some browsers will only obtain the filename correctly - * if the extension is the last argument in the query - * string and rest of the filename appears in the - * PATH_INFO element. */ - $filename = rawurlencode($filename); - - /* Get the webserver ID. */ - $server = Horde::webServerID(); - - /* Get the name and extension of the file. Apache 2 does - * NOT support PATH_INFO information being passed to the - * PHP module by default, so disable that - * functionality. */ - if (($server != 'apache2')) { - if (($pos = strrpos($filename, '.'))) { - $name = '/' . preg_replace('/\./', '%2E', substr($filename, 0, $pos)); - $ext = substr($filename, $pos); - } else { - $name = '/' . $filename; - $ext = ''; - } - - /* Enter the PATH_INFO information. */ - if (($pos = strpos($url, '?'))) { - $url = substr($url, 0, $pos) . $name . substr($url, $pos); - } else { - $url .= $name; - } - } - - /* Append the extension, if it exists. */ - if (($server == 'apache2') || !empty($ext)) { - $url = Util::addParameter($url, 'fn_ext=/' . $filename); - } - } - - return $url; - } - - /** - * Returns an anchor tag with the relevant parameters - * - * @access public - * - * @param string $url The full URL to be linked to - * @param string $status The JavaScript mouse-over string - * @param string $class The CSS class of the link - * @param string $target The window target to point to. - * @param string $onclick JavaScript action for the 'onclick' event. - * @param string $title The link title (tooltip). - * @param string $accesskey The access key to use. - * @param array $attributes Any other name/value pairs to add to the - * tag. - * - * @return string The full tag. - */ - function link($url, $status = '', $class = '', $target = '', $onclick = '', - $title = '', $accesskey = '', $attributes = array()) - { - $ret = " '', "\n" => '')), ENT_QUOTES, NLS::getCharset()) . '\'; return true;"'; - } - if (!empty($class)) { - $ret .= " class=\"$class\""; - } - if (!empty($target)) { - $ret .= " target=\"$target\""; - } - if (!empty($title)) { - $ret .= ' title="' . @htmlspecialchars($title, ENT_QUOTES, NLS::getCharset()) . '"'; - } - if (!empty($accesskey)) { - $ret .= ' accesskey="' . htmlspecialchars($accesskey) . '"'; - } - - foreach ($attributes as $name => $value) { - $ret .= ' ' . htmlspecialchars($name) . '="' . htmlspecialchars($value) . '"'; - } - - return "$ret>"; - } - - /** - * Returns an anchor sequence with the relevant parameters for a widget - * with accesskey and text. - * - * @access public - * - * @param string $url The full URL to be linked to - * @param string $status The JavaScript mouse-over string - * @param string $class The CSS class of the link - * @param string $target The window target to point to. - * @param string $onclick JavaScript action for the 'onclick' event. - * @param string $title The link title (tooltip). - * @param boolean $nocheck Don't check if the access key already has been - * used? - * - * @return string The full Title sequence. - */ - function widget($url, $status = '', $class = 'widget', $target = '', - $onclick = '', $title = '', $nocheck = false) - { - $ak = Horde::getAccessKey($title, $nocheck); - $plaintitle = Horde::stripAccessKey($title); - - return Horde::link($url, $status, $class, $target, $onclick, $plaintitle, $ak) . Horde::highlightAccessKey($title, $ak) . ''; - } - - /** - * Returns a session-id-ified version of $PHP_SELF. - * - * @access public - * - * @param boolean $query_string Include any QUERY_STRING? - * @param boolean $nocache Include a nocache parameter in the URL? - * @param boolean $full Return a full URL? - * - * @return string The requested URI. - */ - function selfUrl($query_string = false, $nocache = true, $full = false, - $force_ssl = false) - { - $url = $_SERVER['PHP_SELF']; - - if ($query_string && !empty($_SERVER['QUERY_STRING'])) { - $url .= '?' . $_SERVER['QUERY_STRING']; - } - - $url = Horde::url($url, $full, 0, $force_ssl); - - if ($nocache) { - return Util::nocacheUrl($url); - } else { - return $url; - } - } - - /** - * Constructs a correctly-pathed link to an image. - * - * @access public - * - * @param string $src The image file. - * @param optional string $alt Text describing the image. - * @param optional mixed $attr Any additional attributes for the image tag. - * Can be a pre-built string or an array of key/value - * pairs that will be assembled and html-encoded. - * @param optional string $dir The root graphics directory. - * - * @return string The full image tag. - */ - function img($src, $alt = '', $attr = '', $dir = null) - { - /* If browser does not support images, simply return the ALT text. */ - if (!$GLOBALS['browser']->hasFeature('images')) { - return @htmlspecialchars($alt, ENT_COMPAT, NLS::getCharset()); - } - - /* If no directory has been specified, get it from the registry. */ - if ($dir === null) { - global $registry; - $dir = $registry->getImageDir(); - } - - /* If a directory has been provided, prepend it to the image source. */ - if (!empty($dir)) { - $src = $dir . '/' . $src; - } - - /* Build all of the tag attributes. */ - $attributes = array('src' => $src, - 'alt' => $alt, - 'title' => $alt); - if (is_array($attr)) { - $attributes = array_merge($attributes, $attr); - } - - $img = ' $value) { - $img .= ' ' . $attribute . '="' . ($attribute == 'src' ? $value : @htmlspecialchars($value, ENT_COMPAT, NLS::getCharset())) . '"'; - } - - /* If the user supplied a pre-built string of attributes, add that. */ - if (is_string($attr) && !empty($attr)) { - $img .= ' ' . $attr; - } - - /* Return the closed image tag. */ - return $img . ' />'; - } - - /** - * Determines the location of the system temporary directory. If a specific - * setting cannot be found, it defaults to /tmp. - * - * @access public - * - * @return string A directory name which can be used for temp files. - * Returns false if one could not be found. - */ - function getTempDir() - { - global $conf; - - /* If one has been specifically set, then use that */ - if (!empty($conf['tmpdir'])) { - $tmp = $conf['tmpdir']; - } - - /* Next, try Util::getTempDir(). */ - if (empty($tmp)) { - $tmp = Util::getTempDir(); - } - - /* 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) registers it to be deleted at request shutdown. - * - * @access public - * - * @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 or - * false if a temporary file could not be created. - */ - function getTempFile($prefix = 'Horde', $delete = true, $dir = '', - $secure = false) - { - if (empty($dir) || !is_dir($dir)) { - $dir = Horde::getTempDir(); - } - - return Util::getTempFile($prefix, $delete, $dir, $secure); - } - - /** - * Starts output compression, if requested. - * - * @access public - * - * @since Horde 2.2 - */ - function compressOutput() - { - static $started; - - if (isset($started)) { - return; - } - - /* Compress output if requested and possible. */ - if ($GLOBALS['conf']['compress_pages'] && - !$GLOBALS['browser']->hasQuirk('buggy_compression') && - ini_get('zlib.output_compression') == '' && - ini_get('output_handler') != 'ob_gzhandler') { - if (ob_get_level()) { - ob_end_clean(); - } - ob_start('ob_gzhandler'); - } - - $started = true; - } - - /** - * Determines if output compression can be used. - * - * @access public - * - * @return boolean True if output compression can be used, false if not. - */ - function allowOutputCompression() - { - require_once 'Horde/Browser.php'; - $browser = &Browser::singleton(); - - /* Turn off compression for buggy browsers. */ - if ($browser->hasQuirk('buggy_compression')) { - return false; - } - - return (ini_get('zlib.output_compression') == '' && - ini_get('output_handler') != 'ob_gzhandler'); - } - - /** - * Returns the Web server being used. - * PHP string list built from the PHP 'configure' script. - * - * @access public - * - * @return string A web server identification string. - *
-     * 'aolserver' = AOL Server
-     * 'apache1'   = Apache 1.x
-     * 'apache2'   = Apache 2.x
-     * 'caudium'   = Caudium
-     * 'cgi'       = Unknown server - PHP built as CGI program
-     * 'cli'       = Command Line Interface build
-     * 'embed'     = Embedded PHP
-     * 'isapi'     = Zeus ISAPI
-     * 'milter'    = Milter
-     * 'nsapi'     = NSAPI
-     * 'phttpd'    = PHTTPD
-     * 'pi3web'    = Pi3Web
-     * 'roxen'     = Roxen/Pike
-     * 'servlet'   = Servlet
-     * 'thttpd'    = thttpd
-     * 'tux'       = Tux
-     * 'webjames'  = Webjames
-     * 
- */ - function webServerID() - { - $server = php_sapi_name(); - - if ($server == 'apache') { - return 'apache1'; - } elseif (($server == 'apache2filter') || - ($server == 'apache2handler')) { - return 'apache2'; - } else { - return $server; - } - } - - /** - * Returns the tags for the CSS stylesheets. - * - * @access public - * - * @param string|array $app The Horde application(s). - * @param mixed $theme The theme to use; specify an empty value to - * retrieve the theme from user preferences, and - * false for no theme. - * @param boolean $inherit Inherit Horde-wide CSS? - * - * @return string tags for CSS stylesheets. - */ - function stylesheetLink($apps = null, $theme = '', $inherit = true) - { - if ($theme !== false && empty($theme)) { - $theme = $GLOBALS['prefs']->getValue('theme'); - } - - $css = array(); - $themes_fs = $GLOBALS['registry']->get('themesfs', 'horde'); - if ($inherit) { - $themes_uri = Horde::url($GLOBALS['registry']->get('themesuri', 'horde'), false, -1); - $css[] = $themes_uri . '/screen.css'; - if (!empty($theme) && - file_exists($themes_fs . '/' . $theme . '/screen.css')) { - $css[] = $themes_uri . '/' . $theme . '/screen.css'; - } - } - - if (!empty($apps)) { - if (!is_array($apps)) { - $apps = array($apps); - } - foreach ($apps as $app) { - if ($inherit && $app == 'horde') { - continue; - } - - $themes_fs = $GLOBALS['registry']->get('themesfs', $app); - if (file_exists($themes_fs . '/screen.css')) { - $themes_uri = Horde::url($GLOBALS['registry']->get('themesuri', $app), false, -1); - $css[] = $themes_uri . '/screen.css'; - } - if (!empty($theme) && - file_exists($themes_fs . '/' . $theme . '/screen.css')) { - $css[] = $themes_uri . '/' . $theme . '/screen.css'; - } - } - } - - $html = ''; - foreach ($css as $css_link) { - $html .= '' . "\n"; - } - - /* Load IE PNG transparency code if needed. */ - if ($GLOBALS['browser']->hasQuirk('png_transparency') && - $GLOBALS['prefs']->getValue('alpha_filter')) { - $url = Horde::url($GLOBALS['registry']->get('jsuri', 'horde') . '/alphaImageLoader.php', true, -1); - $html .= ''; - } - - /* Load browser specific stylesheets if needed. */ - if ($GLOBALS['browser']->isBrowser('msie')) { - $html .= '' . "\n"; - if ($GLOBALS['browser']->getPlatform() == 'mac') { - $html .= '' . "\n"; - } - } - if ($GLOBALS['browser']->isBrowser('opera')) { - $html .= '' . "\n"; - } - if (strpos(strtolower($GLOBALS['browser']->getAgentString()), 'safari') !== false) { - $html .= '' . "\n"; - } - - return $html; - } - - /** - * Sets a custom session handler up, if there is one. - * - * @access public - */ - function setupSessionHandler() - { - global $conf; - - ini_set('url_rewriter.tags', 0); - session_set_cookie_params($conf['session']['timeout'], - $conf['cookie']['path'], $conf['cookie']['domain'], $conf['use_ssl'] == 1 ? 1 : 0); - session_cache_limiter($conf['session']['cache_limiter']); - session_name(urlencode($conf['session']['name'])); - - $type = !empty($conf['sessionhandler']['type']) ? $conf['sessionhandler']['type'] : 'none'; - - if ($type == 'external') { - $calls = $conf['sessionhandler']['params']; - session_set_save_handler($calls['open'], - $calls['close'], - $calls['read'], - $calls['write'], - $calls['destroy'], - $calls['gc']); - } elseif ($type != 'none') { - global $_session_handler; - require_once 'Horde/SessionHandler.php'; - $_session_handler = &SessionHandler::singleton($conf['sessionhandler']['type']); - if (!empty($_session_handler) && - !is_a($_session_handler, 'PEAR_Error')) { - ini_set('session.save_handler', 'user'); - session_set_save_handler(array(&$_session_handler, 'open'), - array(&$_session_handler, 'close'), - array(&$_session_handler, 'read'), - array(&$_session_handler, 'write'), - array(&$_session_handler, 'destroy'), - array(&$_session_handler, 'gc')); - } else { - Horde::fatal(PEAR::raiseError('Horde is unable to correctly start the custom session handler.'), __FILE__, __LINE__, false); - } - } - } - - /** - * Returns an un-used access key from the label given. - * - * @access public - * - * @param string $label The label to choose an access key from. - * @param boolean $nocheck Don't check if the access key already has been - * used? - * - * @return string A single lower case character access key or empty - * string if none can be found - */ - function getAccessKey($label, $nocheck = false, $shutdown = false) - { - /* The access keys already used in this page */ - static $_used = array(); - - /* The labels already used in this page */ - static $_labels = array(); - - /* Shutdown call for translators? */ - if ($shutdown) { - if (!count($_labels)) { - return; - } - $script = basename($_SERVER['PHP_SELF']); - $labels = array_keys($_labels); - sort($labels); - $used = array_keys($_used); - sort($used); - $remaining = str_replace($used, array(), 'abcdefghijklmnopqrstuvwxyz'); - Horde::logMessage('Access key information for ' . $script, __FILE__, __LINE__); - Horde::logMessage('Used labels: ' . implode(',', $labels), __FILE__, __LINE__); - Horde::logMessage('Used keys: ' . implode('', $used), __FILE__, __LINE__); - Horde::logMessage('Free keys: ' . $remaining, __FILE__, __LINE__); - return; - } - - /* Use access keys at all? */ - static $notsupported; - if (!isset($notsupported)) { - $notsupported = !$GLOBALS['browser']->hasFeature('accesskey') || - !$GLOBALS['prefs']->getValue('widget_accesskey'); - } - - if ($notsupported || !preg_match('/_([A-Za-z])/', $label, $match)) { - return ''; - } - $key = $match[1]; - - /* Has this key already been used? */ - if (isset($_used[strtolower($key)]) && - !($nocheck && isset($_labels[$label]))) { - return ''; - } - - /* Save key and label. */ - $_used[strtolower($key)] = true; - $_labels[$label] = true; - - return $key; - } - - /** - * Strips an access key from a label. - * For multibyte charset strings the access key gets removed completely, - * otherwise only the underscore gets removed. - * - * @access public - * - * @param string $label The label containing an access key. - * - * @return string The label with the access key being stripped. - */ - function stripAccessKey($label) - { - include_once HORDE_BASE . '/config/nls.php'; - $multibyte = isset($GLOBALS['nls']['multibyte'][NLS::getCharset(true)]); - - return preg_replace('/_([A-Za-z])/', - $multibyte && preg_match('/[\x80-\xff]/', $label) ? '' : '\1', - $label); - } - - /** - * Highlights an access key in a label. - * - * @access public - * - * @param string $label The label to to highlight the access key in. - * @param string $accessKey The access key to highlight. - * - * @return string The HTML version of the label with the access key - * highlighted. - */ - function highlightAccessKey($label, $accessKey) - { - $stripped_label = Horde::stripAccesskey($label); - - if (empty($accessKey)) { - return $stripped_label; - } - - if (isset($GLOBALS['nls']['multibyte'][NLS::getCharset(true)])) { - return $stripped_label . '(' . '' . - strtoupper($accessKey) . '' . ')'; - } else { - return str_replace('_' . $accessKey, '' . $accessKey . '', $label); - } - } - - /** - * Returns the appropriate "accesskey" and "title" attributes for an HTML - * tag and the given label. - * - * @param string $label The title of an HTML element - * @param boolean $nocheck Don't check if the access key already has been - * used? - * - * @return string The title, and if appropriate, the accesskey attributes - * for the element. - */ - function getAccessKeyAndTitle($label, $nocheck = false) - { - $ak = Horde::getAccessKey($label, $nocheck); - $attributes = 'title="' . Horde::stripAccessKey($label); - if (!empty($ak)) { - $attributes .= sprintf(_(" (Accesskey %s)"), $ak); - $attributes .= '" accesskey="' . $ak; - } - $attributes .= '"'; - return $attributes; - } - - /** - * Returns a label element including an access key for usage in conjuction - * with a form field. User preferences regarding access keys are respected. - * - * @param string $for The form field's id attribute. - * @param string $label The label text. - * @param string $ak The access key to use. If null a new access key - * will be generated. - * - * @return string The html code for the label element. - */ - function label($for, $label, $ak = null) - { - global $prefs; - - if (is_null($ak)) { - $ak = Horde::getAccesskey($label, 1); - } - $label = Horde::highlightAccessKey($label, $ak); - - return sprintf('', - $for, - !empty($ak) ? ' accesskey="' . $ak . '"' : '', - $label); - } - - /** - * Redirects to the main Horde login page on authentication failure. - * - * @access public - */ - function authenticationFailureRedirect() - { - require_once 'Horde/CLI.php'; - if (Horde_CLI::runningFromCLI()) { - $cli = &Horde_CLI::singleton(); - $cli->fatal(_("You are not authenticated.")); - } - - $url = $GLOBALS['registry']->get('webroot', 'horde') . '/login.php'; - $url = Util::addParameter($url, 'url', Horde::selfUrl(true)); - $url = Auth::addLogoutParameters($url); - header('Location: ' . Horde::url($url, true)); - exit; - } - - /** - * Uses DOM Tooltips (via javascript) to display the 'title' - * attribute for Horde::link() calls. - * - * If using this function, the following function must be called: - * Horde::addScriptFile('tooltip.js', 'horde', true); - * - * @access public - * - * @param string $url The full URL to be linked to - * @param string $status The JavaScript mouse-over string - * @param string $class The CSS class of the link - * @param string $target The window target to point to. - * @param string $onclick JavaScript action for the 'onclick' event. - * @param string $title The link title (tooltip). - * @param string $accesskey The access key to use. - * @param array $attributes Any other name/value pairs to add to the - * tag. - * - * @return string The full tag. - */ - function linkTooltip($url, $status = '', $class = '', $target = '', - $onclick = '', $title = '', $accesskey = '', - $attributes = array()) - { - $url = substr(Horde::link($url, null, $class, $target, $onclick, null, $accesskey, $attributes), 0, -1); - - if (strlen($status)) { - $status = @htmlspecialchars(addslashes($status), ENT_QUOTES, NLS::getCharset()); - } - - $title = trim($title); - if (strlen($title)) { - require_once 'Horde/Text/Filter.php'; - $title = Text_Filter::filter($title, 'text2html', array('parselevel' => TEXT_HTML_NOHTML, 'charset' => '', 'class' => '')); - $title = '
' . strtr(addslashes($title), array("\r" => '', "\n" => '')) . '
'; - $url .= ' onmouseover="tooltipLink(\'' . @htmlspecialchars($title, ENT_QUOTES, NLS::getCharset()) . '\', \'' . $status . '\'); return true;" onmouseout="tooltipClose();"'; - } - $url .= '>'; - - return $url; - } - - /** - * Provides a standardised function to call a Horde hook, checking whether - * a hook config file exists and whether the function itself exists. If - * these two conditions are not satisfied it will return the specified - * value (by default a PEAR error). - * - * @access public - * - * @param string $hook The function to call. - * @param array $args An array of any arguments to pass to the hook - * function. - * @param string $app If specified look for hooks in the config directory - * of this app. - * @param mixed $error What to return if $app/config/hooks.php or $hook - * does not exist. If this is the string 'PEAR_Error' - * a PEAR error object is returned instead, detailing - * the failure. - * - * @return mixed Either the results of the hook or PEAR error on failure. - */ - function callHook($hook, $args = array(), $app = 'horde', $error = 'PEAR_Error') - { - global $registry; - static $hooks_loaded; - - if (!isset($hooks_loaded)) { - if (file_exists($registry->get('fileroot', $app) . '/config/hooks.php')) { - require_once $registry->get('fileroot', $app) . '/config/hooks.php'; - $hooks_loaded = true; - } else { - $hooks_loaded = false; - } - } - if ($hooks_loaded && function_exists($hook)) { - return call_user_func_array($hook, $args); - } - - if (is_string($error) && strcmp($error, 'PEAR_Error') == 0) { - $error = PEAR::raiseError(sprintf('Hook %s in application %s not called.', $hook, $app)); - Horde::logMessage($error, __FILE__, __LINE__, PEAR_LOG_DEBUG); - } - - return $error; - } - - /** - * Return the initial page to load when accessing Horde. - * - * @return string The URL of the initial page. - */ - function initialPage() - { - global $prefs, $registry, $perms; - - $initial_app = $prefs->getValue('initial_application'); - if (!empty($initial_app) && $registry->hasPermission($initial_app)) { - return Horde::url($registry->getInitialPage($initial_app), true); - } elseif (isset($registry->applications['horde']['initial_page'])) { - return Horde::applicationUrl($registry->applications['horde']['initial_page'], true); - } elseif (Auth::getAuth()) { - return Horde::applicationUrl('services/portal/', true); - } else { - return Horde::applicationUrl('login.php', true); - } - } - - /** - * Returns an array of available menu items when in a Horde script. - * - * @return array Available menu items. - */ - function getHordeMenu() - { - global $registry, $prefs; - - $menu = array(); - - /* The home page button. If an initial application has been set in the - * prefs this will default to that application. Otherwise it will go - * to the portal screen. */ - $initial_app = $prefs->getValue('initial_application'); - if (!empty($initial_app)) { - $url = Horde::url($registry->getInitialPage($initial_app)); - } else { - $url = Horde::applicationUrl('services/portal/'); - } - $menu[] = array('url' => $url, - 'text' => _("Home"), - 'icon' => 'horde.png', - 'icon_path' => $registry->getImageDir()); - - if (Auth::isAdmin()) { - $menu[] = array('url' => Horde::applicationUrl('admin/'), - 'text' => _("_Administration"), - 'icon' => 'administration.png', - 'icon_path' => $registry->getImageDir()); - } - - return $menu; - } - -} diff --git a/phpgwapi/inc/horde/Horde/Browser.php b/phpgwapi/inc/horde/Horde/Browser.php deleted file mode 100644 index 4f09993479..0000000000 --- a/phpgwapi/inc/horde/Horde/Browser.php +++ /dev/null @@ -1,1082 +0,0 @@ - - * Copyright 1999-2005 Jon Parise - * - * 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 - * @author Jon Parise - * @since Horde 1.3 - * @package Horde_Browser - */ -class Browser { - - /** - * Major version number. - * - * @var integer $_majorVersion - */ - var $_majorVersion = 0; - - /** - * Minor version number. - * - * @var integer $_minorVersion - */ - var $_minorVersion = 0; - - /** - * Browser name. - * - * @var string $_browser - */ - var $_browser = ''; - - /** - * Full user agent string. - * - * @var string $_agent - */ - var $_agent = ''; - - /** - * Lower-case user agent string. - * - * @var string $_agent - */ - var $_lowerAgent = ''; - - /** - * HTTP_ACCEPT string - * - * @var string $_accept - */ - var $_accept = ''; - - /** - * Platform the browser is running on. - * - * @var string $_platform - */ - var $_platform = ''; - - /** - * Known robots. - * - * @var array $_robots - */ - var $_robots = array( - /* The most common ones. */ - 'Googlebot', - 'msnbot', - 'Slurp', - 'Yahoo', - /* The rest alphabetically. */ - 'Arachnoidea', - 'ArchitextSpider', - 'Ask Jeeves', - 'B-l-i-t-z-Bot', - 'ConveraCrawler', - 'ExtractorPro', - 'FAST-WebCrawler', - 'FDSE robot', - 'fido', - 'geckobot', - 'Gigabot', - 'Girafabot', - 'grub-client', - 'Gulliver', - 'ia_archiver', - 'InfoSeek', - 'KIT-Fireball', - 'LEIA', - 'Lycos_Spider', - 'Mediapartners-Google', - 'MuscatFerret', - 'NaverBot', - 'polybot', - 'Pompos', - 'Scooter', - 'Teoma', - 'TurnitinBot', - 'Ultraseek', - 'ViolaBot', - 'webbandit', - 'www.almaden.ibm.com/cs/crawler', - 'ZyBorg', - ); - - /** - * Is this a mobile browser? - * - * @var boolean $_mobile - */ - var $_mobile = false; - - /** - * Features. - * - * @var array $_features - */ - var $_features = array( - 'html' => true, - 'hdml' => false, - 'wml' => false, - 'images' => true, - 'iframes' => false, - 'frames' => true, - 'tables' => true, - 'java' => true, - 'javascript' => true, - 'dom' => false, - 'utf' => false, - 'rte' => false, - 'homepage' => false, - 'accesskey' => false, - 'optgroup' => false, - 'xmlhttpreq' => false, - 'cite' => false, - ); - - /** - * Quirks - * - * @var array $_quirks - */ - var $_quirks = array( - 'avoid_popup_windows' => false, - 'break_disposition_header' => false, - 'break_disposition_filename' => false, - 'broken_multipart_form' => false, - 'buggy_compression' => false, - 'cache_same_url' => false, - 'cache_ssl_downloads' => false, - 'double_linebreak_textarea' => false, - 'empty_file_input_value' => false, - 'must_cache_forms' => false, - 'no_filename_spaces' => false, - 'no_hidden_overflow_tables' => false, - 'ow_gui_1.3' => false, - 'png_transparency' => false, - 'scrollbar_in_way' => false, - 'scroll_tds' => false, - ); - - /** - * List of viewable image MIME subtypes. - * This list of viewable images works for IE and Netscape/Mozilla. - * - * @var array $_images - */ - var $_images = array('jpeg', 'gif', 'png', 'pjpeg', 'x-png', 'bmp'); - - /** - - /** - * Returns a reference to the global Browser object, only creating it - * if it doesn't already exist. - * - * This method must be invoked as: - * $browser = &Browser::singleton([$userAgent[, $accept]]); - * - * @access public - * - * @param optional string $userAgent The browser string to parse. - * @param optional string $accept The HTTP_ACCEPT settings to use. - * - * @return object Browser The Browser object. - */ - function &singleton($userAgent = null, $accept = null) - { - static $instances; - - if (!isset($instances)) { - $instances = array(); - } - - $signature = serialize(array($userAgent, $accept)); - if (empty($instances[$signature])) { - $instances[$signature] = new Browser($userAgent, $accept); - } - - return $instances[$signature]; - } - - /** - * Create a browser instance (Constructor). - * - * @access public - * - * @param optional string $userAgent The browser string to parse. - * @param optional string $accept The HTTP_ACCEPT settings to use. - */ - function Browser($userAgent = null, $accept = null) - { - $this->match($userAgent, $accept); - } - - /** - * Parses the user agent string and inititializes the object with - * all the known features and quirks for the given browser. - * - * @access public - * - * @param optional string $userAgent The browser string to parse. - * @param optional string $accept The HTTP_ACCEPT settings to use. - */ - function match($userAgent = null, $accept = null) - { - // Set our agent string. - if (is_null($userAgent)) { - if (isset($_SERVER['HTTP_USER_AGENT'])) { - $this->_agent = trim($_SERVER['HTTP_USER_AGENT']); - } - } else { - $this->_agent = $userAgent; - } - $this->_lowerAgent = 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'])); - } - } else { - $this->_accept = 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); - } - - if (!empty($this->_agent)) { - $this->_setPlatform(); - - if (preg_match('|Opera[/ ]([0-9.]+)|', $this->_agent, $version)) { - $this->setBrowser('opera'); - list($this->_majorVersion, $this->_minorVersion) = explode('.', $version[1]); - $this->setFeature('javascript', true); - $this->setQuirk('no_filename_spaces'); - - switch ($this->_majorVersion) { - case 7: - $this->setFeature('dom'); - $this->setFeature('iframes'); - $this->setFeature('accesskey'); - $this->setFeature('optgroup'); - $this->setQuirk('double_linebreak_textarea'); - break; - } - } elseif (strpos($this->_lowerAgent, 'elaine/') !== false || - strpos($this->_lowerAgent, 'palmsource') !== false || - strpos($this->_lowerAgent, 'digital paths') !== false) { - $this->setBrowser('palm'); - $this->setFeature('images', false); - $this->setFeature('frames', false); - $this->setFeature('javascript', false); - $this->setQuirk('avoid_popup_windows'); - $this->_mobile = true; - } elseif ((preg_match('|MSIE ([0-9.]+)|', $this->_agent, $version)) || - (preg_match('|Internet Explorer/([0-9.]+)|', $this->_agent, $version))) { - - $this->setBrowser('msie'); - $this->setQuirk('cache_ssl_downloads'); - $this->setQuirk('cache_same_url'); - $this->setQuirk('break_disposition_filename'); - - if (strpos($version[1], '.') !== false) { - list($this->_majorVersion, $this->_minorVersion) = explode('.', $version[1]); - } else { - $this->_majorVersion = $version[1]; - $this->_minorVersion = 0; - } - - /* IE on Windows does not support alpha transparency in PNG - * images. */ - if (preg_match('/windows/i', $this->_agent)) { - $this->setQuirk('png_transparency'); - } - - /* IE 6 (pre-SP1) and 5.5 (pre-SP1) has buggy compression. - * The versions affected are as follows: - * 6.00.2462.0000 Internet Explorer 6 Public Preview (Beta) - * 6.00.2479.0006 Internet Explorer 6 Public Preview (Beta) - Refresh - * 6.00.2600.0000 Internet Explorer 6 (Windows XP) - * 5.50.3825.1300 Internet Explorer 5.5 Developer Preview (Beta) - * 5.50.4030.2400 Internet Explorer 5.5 & Internet Tools Beta - * 5.50.4134.0100 Internet Explorer 5.5 for Windows Me (4.90.3000) - * 5.50.4134.0600 Internet Explorer 5.5 - * 5.50.4308.2900 Internet Explorer 5.5 Advanced Security Privacy Beta - * - * See: - * ==== - * http://support.microsoft.com/kb/164539; - * http://support.microsoft.com/default.aspx?scid=kb;en-us;Q312496) - * http://support.microsoft.com/default.aspx?scid=kb;en-us;Q313712 - */ - $ie_vers = $this->getIEVersion(); - $buggy_list = array( - '6,00,2462,0000', '6,00,2479,0006', '6,00,2600,0000', - '5,50,3825,1300', '5,50,4030,2400', '5,50,4134,0100', - '5,50,4134,0600', '5,50,4308,2900' - ); - if (!is_null($ie_vers) && in_array($ie_vers, $buggy_list)) { - $this->setQuirk('buggy_compression'); - } - - /* Some Handhelds have their screen resolution in the - * user agent string, which we can use to look for - * mobile agents. */ - if (preg_match('/; (120x160|240x280|240x320)\)/', $this->_agent)) { - $this->_mobile = true; - } - - switch ($this->_majorVersion) { - case 6: - $this->setFeature('javascript', 1.4); - $this->setFeature('dom'); - $this->setFeature('iframes'); - $this->setFeature('utf'); - $this->setFeature('rte'); - $this->setFeature('homepage'); - $this->setFeature('accesskey'); - $this->setFeature('optgroup'); - $this->setFeature('xmlhttpreq'); - $this->setQuirk('scrollbar_in_way'); - $this->setQuirk('broken_multipart_form'); - break; - - case 5: - if ($this->getPlatform() == 'mac') { - $this->setFeature('javascript', 1.2); - $this->setFeature('optgroup'); - } else { - // MSIE 5 for Windows. - $this->setFeature('javascript', 1.4); - $this->setFeature('dom'); - $this->setFeature('xmlhttpreq'); - if ($this->_minorVersion >= 5) { - $this->setFeature('rte'); - } - } - $this->setFeature('iframes'); - $this->setFeature('utf'); - $this->setFeature('homepage'); - $this->setFeature('accesskey'); - if ($this->_minorVersion == 5) { - $this->setQuirk('break_disposition_header'); - $this->setQuirk('broken_multipart_form'); - } - break; - - case 4: - $this->setFeature('javascript', 1.2); - $this->setFeature('accesskey'); - if ($this->_minorVersion > 0) { - $this->setFeature('utf'); - } - break; - - case 3: - $this->setFeature('javascript', 1.1); - $this->setQuirk('avoid_popup_windows'); - break; - } - } elseif (preg_match('|ANTFresco/([0-9]+)|', $this->_agent, $version)) { - $this->setBrowser('fresco'); - $this->setFeature('javascript', 1.1); - $this->setQuirk('avoid_popup_windows'); - } elseif (strpos($this->_lowerAgent, 'avantgo') !== false) { - $this->setBrowser('avantgo'); - $this->_mobile = true; - } elseif (preg_match('|Konqueror/([0-9]+)|', $this->_agent, $version) || - preg_match('|Safari/([0-9]+)\.?([0-9]+)?|', $this->_agent, $version)) { - // Konqueror and Apple's Safari both use the KHTML - // rendering engine. - $this->setBrowser('konqueror'); - $this->setQuirk('empty_file_input_value'); - $this->setQuirk('no_hidden_overflow_tables'); - $this->_majorVersion = $version[1]; - if (isset($version[2])) { - $this->_minorVersion = $version[2]; - } - - if (strpos($this->_agent, 'Safari') !== false && - $this->_majorVersion >= 60) { - // Safari. - $this->setFeature('utf'); - $this->setFeature('javascript', 1.4); - $this->setFeature('dom'); - $this->setFeature('iframes'); - if ($this->_majorVersion > 125 || - ($this->_majorVersion == 125 && - $this->_minorVersion >= 1)) { - $this->setFeature('utf'); - $this->setFeature('accesskey'); - $this->setFeature('xmlhttpreq'); - } - } else { - // Konqueror. - $this->setFeature('javascript', 1.1); - switch ($this->_majorVersion) { - case 3: - $this->setFeature('dom'); - $this->setFeature('iframes'); - break; - } - } - } elseif (preg_match('|Mozilla/([0-9.]+)|', $this->_agent, $version)) { - $this->setBrowser('mozilla'); - $this->setQuirk('must_cache_forms'); - - list($this->_majorVersion, $this->_minorVersion) = explode('.', $version[1]); - switch ($this->_majorVersion) { - case 5: - if ($this->getPlatform() == 'win') { - $this->setQuirk('break_disposition_filename'); - } - $this->setFeature('javascript', 1.4); - $this->setFeature('dom'); - $this->setFeature('accesskey'); - $this->setFeature('optgroup'); - $this->setFeature('xmlhttpreq'); - $this->setFeature('cite'); - if (preg_match('|rv:(.*)\)|', $this->_agent, $revision)) { - if ($revision[1] >= 1) { - $this->setFeature('iframes'); - } - if ($revision[1] >= 1.3) { - $this->setFeature('rte'); - } - } - break; - - case 4: - $this->setFeature('javascript', 1.3); - $this->setQuirk('buggy_compression'); - break; - - case 3: - default: - $this->setFeature('javascript', 1); - $this->setQuirk('buggy_compression'); - break; - } - } elseif (preg_match('|Lynx/([0-9]+)|', $this->_agent, $version)) { - $this->setBrowser('lynx'); - $this->setFeature('images', false); - $this->setFeature('frames', false); - $this->setFeature('javascript', false); - $this->setQuirk('avoid_popup_windows'); - } elseif (preg_match('|Links \(([0-9]+)|', $this->_agent, $version)) { - $this->setBrowser('links'); - $this->setFeature('images', false); - $this->setFeature('frames', false); - $this->setFeature('javascript', false); - $this->setQuirk('avoid_popup_windows'); - } elseif (preg_match('|HotJava/([0-9]+)|', $this->_agent, $version)) { - $this->setBrowser('hotjava'); - $this->setFeature('javascript', false); - } elseif (strpos($this->_agent, 'UP/') !== false || - strpos($this->_agent, 'UP.B') !== false || - strpos($this->_agent, 'UP.L') !== false) { - $this->setBrowser('up'); - $this->setFeature('html', false); - $this->setFeature('javascript', false); - $this->setFeature('hdml'); - $this->setFeature('wml'); - - if (strpos($this->_agent, 'GUI') !== false && - strpos($this->_agent, 'UP.Link') !== false) { - /* The device accepts Openwave GUI extensions for - * WML 1.3. Non-UP.Link gateways sometimes have - * problems, so exclude them. */ - $this->setQuirk('ow_gui_1.3'); - } - $this->_mobile = true; - } elseif (strpos($this->_agent, 'Xiino/') !== false) { - $this->setBrowser('xiino'); - $this->setFeature('hdml'); - $this->setFeature('wml'); - $this->_mobile = true; - } elseif (strpos($this->_agent, 'Palmscape/') !== false) { - $this->setBrowser('palmscape'); - $this->setFeature('javascript', false); - $this->setFeature('hdml'); - $this->setFeature('wml'); - $this->_mobile = true; - } elseif (strpos($this->_agent, 'Nokia') !== false) { - $this->setBrowser('nokia'); - $this->setFeature('html', false); - $this->setFeature('wml'); - $this->setFeature('xhtml'); - $this->_mobile = true; - } elseif (strpos($this->_agent, 'Ericsson') !== false) { - $this->setBrowser('ericsson'); - $this->setFeature('html', false); - $this->setFeature('wml'); - $this->_mobile = true; - } elseif (strpos($this->_lowerAgent, 'wap') !== false) { - $this->setBrowser('wap'); - $this->setFeature('html', false); - $this->setFeature('javascript', false); - $this->setFeature('hdml'); - $this->setFeature('wml'); - $this->_mobile = true; - } elseif (strpos($this->_lowerAgent, 'docomo') !== false || - strpos($this->_lowerAgent, 'portalmmm') !== false) { - $this->setBrowser('imode'); - $this->setFeature('images', false); - $this->_mobile = true; - } elseif (strpos($this->_lowerAgent, 'j-') !== false) { - $this->setBrowser('mml'); - $this->_mobile = true; - } - } - } - - /** - * Match the platform of the browser. - * - * This is a pretty simplistic implementation, but it's intended - * to let us tell what line breaks to send, so it's good enough - * for its purpose. - * - * @access public - * - * @since Horde 2.2 - */ - function _setPlatform() - { - if (strpos($this->_lowerAgent, 'wind') !== false) { - $this->_platform = 'win'; - } elseif (strpos($this->_lowerAgent, 'mac') !== false) { - $this->_platform = 'mac'; - } else { - $this->_platform = 'unix'; - } - } - - /** - * Return the currently matched platform. - * - * @return string The user's platform. - * - * @since Horde 2.2 - */ - function getPlatform() - { - return $this->_platform; - } - - /** - * Sets the current browser. - * - * @access public - * - * @param string $browser The browser to set as current. - */ - function setBrowser($browser) - { - $this->_browser = $browser; - } - - /** - * Determine if the given browser is the same as the current. - * - * @access public - * - * @param string $browser The browser to check. - * - * @return boolean Is the given browser the same as the current? - */ - function isBrowser($browser) - { - return ($this->_browser === $browser); - } - - /** - * Do we consider the current browser to be a mobile device? - * - * @return boolean True if we do, false if we don't. - */ - function isMobile() - { - return $this->_mobile; - } - - /** - * Determines if the browser is a robot or not. - * - * @access public - * - * @return boolean True if browser is a known robot. - */ - function isRobot() - { - foreach ($this->_robots as $robot) { - if (strpos($this->_agent, $robot) !== false) { - return true; - } - } - return false; - } - - /** - * Retrieve the current browser. - * - * @access public - * - * @return string The current browser. - */ - function getBrowser() - { - return $this->_browser; - } - - /** - * Retrieve the current browser's major version. - * - * @access public - * - * @return integer The current browser's major version. - */ - function getMajor() - { - return $this->_majorVersion; - } - - /** - * Retrieve the current browser's minor version. - * - * @access public - * - * @return integer The current browser's minor version. - */ - function getMinor() - { - return $this->_minorVersion; - } - - /** - * Retrieve the current browser's version. - * - * @access public - * - * @return string The current browser's version. - */ - function getVersion() - { - return $this->_majorVersion . '.' . $this->_minorVersion; - } - - /** - * Return the full browser agent string. - * - * @access public - * - * @return string The browser agent string. - */ - function getAgentString() - { - return $this->_agent; - } - - /** - * Set unique behavior for the current browser. - * - * @access public - * - * @param string $quirk The behavior to set. - * @param optional string $value Special behavior parameter. - */ - function setQuirk($quirk, $value = true) - { - $this->_quirks[$quirk] = $value; - } - - /** - * Check unique behavior for the current browser. - * - * @access public - * - * @param string $quirk The behavior to check. - * - * @return boolean Does the browser have the behavior set? - */ - function hasQuirk($quirk) - { - return !empty($this->_quirks[$quirk]); - } - - /** - * Retreive unique behavior for the current browser. - * - * @access public - * - * @param string $quirk The behavior to retreive. - * - * @return string The value for the requested behavior. - */ - function getQuirk($quirk) - { - return isset($this->_quirks[$quirk]) - ? $this->_quirks[$quirk] - : null; - } - - /** - * Set capabilities for the current browser. - * - * @access public - * - * @param string $feature The capability to set. - * @param optional string $value Special capability parameter. - */ - function setFeature($feature, $value = true) - { - $this->_features[$feature] = $value; - } - - /** - * Check the current browser capabilities. - * - * @access public - * - * @param string $feature The capability to check. - * - * @return boolean Does the browser have the capability set? - */ - function hasFeature($feature) - { - return !empty($this->_features[$feature]); - } - - /** - * Retreive the current browser capability. - * - * @access public - * - * @param string $feature The capability to retreive. - * - * @return string The value of the requested capability. - */ - function getFeature($feature) - { - return isset($this->_features[$feature]) - ? $this->_features[$feature] - : null; - } - - /** - * Determine if we are using a secure (SSL) connection. - * - * @access public - * - * @return boolean True if using SSL, false if not. - */ - function usingSSLConnection() - { - return ((isset($_SERVER['HTTPS']) && - ($_SERVER['HTTPS'] == 'on')) || - getenv('SSL_PROTOCOL_VERSION')); - } - - /** - * Returns the server protocol in use on the current server. - * - * @access public - * - * @return string The HTTP server protocol version. - */ - function getHTTPProtocol() - { - if (isset($_SERVER['SERVER_PROTOCOL'])) { - if (($pos = strrpos($_SERVER['SERVER_PROTOCOL'], '/'))) { - return substr($_SERVER['SERVER_PROTOCOL'], $pos + 1); - } - } - - return null; - } - - /** - * Determine if files can be uploaded to the system. - * - * @access public - * - * @return integer If uploads allowed, returns the maximum size of the - * upload in bytes. Returns 0 if uploads are not - * allowed. - */ - function allowFileUploads() - { - if (ini_get('file_uploads')) { - if (($dir = ini_get('upload_tmp_dir')) && - !is_writable($dir)) { - return 0; - } - $size = ini_get('upload_max_filesize'); - switch (strtolower(substr($size, -1, 1))) { - case 'k': - $size = intval(floatval($size) * 1024); - break; - - case 'm': - $size = intval(floatval($size) * 1024 * 1024); - break; - - default: - $size = intval($size); - break; - } - return $size; - } else { - return 0; - } - } - - /** - * Determines if the file was uploaded or not. If not, will return the - * appropriate error message. - * - * @access public - * - * @param string $field The name of the field containing the - * uploaded file. - * @param optional string $name The file description string to use in the - * error message. Default: 'file'. - * - * @return mixed True on success, PEAR_Error on error. - */ - function wasFileUploaded($field, $name = null) - { - require_once 'PEAR.php'; - - if (is_null($name)) { - $name = _("file"); - } - - if (!($uploadSize = Browser::allowFileUploads())) { - return PEAR::raiseError(_("File uploads not supported.")); - } - - /* Get any index on the field name. */ - require_once 'Horde/Array.php'; - $index = Horde_Array::getArrayParts($field, $base, $keys); - - if ($index) { - /* Index present, fetch the error var to check. */ - $keys_path = array_merge(array($base, 'error'), $keys); - $error = Horde_Array::getElement($_FILES, $keys_path); - - /* Index present, fetch the tmp_name var to check. */ - $keys_path = array_merge(array($base, 'tmp_name'), $keys); - $tmp_name = Horde_Array::getElement($_FILES, $keys_path); - } else { - /* No index, simple set up of vars to check. */ - if (!isset($_FILES[$field])) { - return PEAR::raiseError(_("No file uploaded"), UPLOAD_ERR_NO_FILE); - } - $error = $_FILES[$field]['error']; - $tmp_name = $_FILES[$field]['tmp_name']; - } - - if (!isset($_FILES) || ($error == UPLOAD_ERR_NO_FILE)) { - return PEAR::raiseError(sprintf(_("There was a problem with the file upload: No %s was uploaded."), $name), UPLOAD_ERR_NO_FILE); - } elseif (($error == UPLOAD_ERR_OK) && is_uploaded_file($tmp_name)) { - 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, $uploadSize), $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); - } - } - - /** - * Returns the headers for a browser download. - * - * @access public - * - * @param optional string $filename The filename of the download. - * @param optional string $cType The content-type description of the - * file. - * @param optional boolean $inline True if inline, false if attachment. - * @param optional string $cLength The content-length of this file. - * - * @since Horde 2.2 - */ - function downloadHeaders($filename = 'unknown', $cType = null, - $inline = false, $cLength = null) - { - /* Some browsers don't like spaces in the filename. */ - if ($this->hasQuirk('no_filename_spaces')) { - $filename = strtr($filename, ' ', '_'); - } - - /* MSIE doesn't like multiple periods in the file name. Convert - all periods (except the last one) to underscores. */ - if ($this->isBrowser('msie')) { - if (($pos = strrpos($filename, '.'))) { - $filename = strtr(substr($filename, 0, $pos), '.', '_') . substr($filename, $pos); - } - } - - /* Content-Type/Content-Disposition Header. */ - if ($inline) { - if (!is_null($cType)) { - header('Content-Type: ' . trim($cType)); - } elseif ($this->isBrowser('msie')) { - header('Content-Type: application/x-msdownload'); - } else { - header('Content-Type: application/octet-stream'); - } - header('Content-Disposition: inline; filename="' . $filename . '"'); - } else { - if ($this->isBrowser('msie')) { - header('Content-Type: application/x-msdownload'); - } elseif (!is_null($cType)) { - header('Content-Type: ' . trim($cType)); - } else { - header('Content-Type: application/octet-stream'); - } - - if ($this->hasQuirk('break_disposition_header')) { - header('Content-Disposition: filename="' . $filename . '"'); - } else { - header('Content-Disposition: attachment; filename="' . $filename . '"'); - } - } - - /* Content-Length Header. Don't send Content-Length for - * HTTP/1.1 servers. */ - if (($this->getHTTPProtocol() != '1.1') && !is_null($cLength)) { - header('Content-Length: ' . $cLength); - } - - /* Overwrite Pragma: and other caching headers for IE. */ - if ($this->hasQuirk('cache_ssl_downloads')) { - header('Expires: 0'); - header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); - header('Pragma: public'); - } - } - - /** - * Determines if a browser can display a given MIME type. - * - * @access public - * - * @param string $mimetype The MIME type to check. - * - * @return boolean True if the browser can display the MIME type. - */ - function isViewable($mimetype) - { - $mimetype = String::lower($mimetype); - list($type, $subtype) = explode('/', $mimetype); - - if (!empty($this->_accept)) { - $wildcard_match = false; - - if (strpos($this->_accept, $mimetype) !== false) { - return true; - } - - if (strpos($this->_accept, '*/*') !== false) { - $wildcard_match = true; - if ($type != 'image') { - return true; - } - } - - /* image/jpeg and image/pjpeg *appear* to be the same - * entity, but Mozilla doesn't seem to want to accept the - * latter. For our purposes, we will treat them the - * same. */ - if ($this->isBrowser('mozilla') && - ($mimetype == 'image/pjpeg') && - (strpos($this->_accept, 'image/jpeg') !== false)) { - return true; - } - - if (!$wildcard_match) { - return false; - } - } - - if (!$this->hasFeature('images') || ($type != 'image')) { - return false; - } - - return (in_array($subtype, $this->_images)); - } - - /** - * Escape characters in javascript code if the browser requires it. - * %23, %26, and %2B (for IE) and %27 need to be escaped or else - * jscript will interpret it as a single quote, pound sign, or - * ampersand and refuse to work. - * - * @access public - * - * @param string $code The JS code to escape. - * - * @return string The escaped code. - */ - function escapeJSCode($code) - { - $from = $to = array(); - - if ($this->isBrowser('msie') || - ($this->isBrowser('mozilla') && ($this->getMajor() >= 5))) { - $from = array('%23', '%26', '%2B'); - $to = array(urlencode('%23'), urlencode('%26'), urlencode('%2B')); - } - $from[] = '%27'; - $to[] = '\%27'; - - return str_replace($from, $to, $code); - } - - /** - * Set the IE version in the session. - * - * @access public - * - * @param string $ver The IE Version string. - */ - function setIEVersion($ver) - { - $_SESSION['__browser'] = array( - 'ie_version' => $ver - ); - } - - /** - * Return the IE version stored in the session, if available. - * - * @access public - * - * @return mixed The IE Version string or null if no string is stored. - */ - function getIEVersion() - { - return isset($_SESSION['__browser']['ie_version']) ? $_SESSION['__browser']['ie_version'] : null; - } - -} diff --git a/phpgwapi/inc/horde/Horde/Browser/imode.php b/phpgwapi/inc/horde/Horde/Browser/imode.php deleted file mode 100644 index 6e0641e7e2..0000000000 --- a/phpgwapi/inc/horde/Horde/Browser/imode.php +++ /dev/null @@ -1,411 +0,0 @@ - - * - * 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 - * @since Horde 3.0 - * @package Horde_Browser - */ -class Browser_imode { - - /** - * Device data. From http://www.nttdocomo.co.jp/i/tag/s5.html#5_1 - * - * @var array $_data - */ - var $_data = array( - 'D209i' => array( - 'imagewidth' => 96, 'imageheight' => 90, - 'textwidth' => 8, 'textheight' => 7, - 'color' => 256, - 'imageformats' => array('gif') - ), - 'F209i' => array( - 'imagewidth' => 96, 'imageheight' => 91, - 'textwidth' => 8, 'textheight' => 7, - 'color' => 256, - 'imageformats' => array('gif') - ), - 'N209i' => array( - 'imagewidth' => 108, 'imageheight' => 82, - 'textwidth' => 9, 'textheight' => 6, - 'color' => 'grey', - 'imageformats' => array('gif') - ), - 'P209i' => array( - 'imagewidth' => 96, 'imageheight' => 87, - 'textwidth' => 8, 'textheight' => 6, - 'color' => 'grey', - 'imageformats' => array('gif') - ), - 'P209is' => array( - 'imagewidth' => 96, 'imageheight' => 87, - 'textwidth' => 8, 'textheight' => 6, - 'color' => 256, - 'imageformats' => array('gif') - ), - 'R209i' => array( - 'imagewidth' => 96, 'imageheight' => 72, - 'textwidth' => 8, 'textheight' => 6, - 'color' => 'grey', - 'imageformats' => array('gif') - ), - 'ER209i' => array( - 'imagewidth' => 120, 'imageheight' => 72, - 'textwidth' => 10, 'textheight' => 6, - 'color' => 'grey', - 'imageformats' => array('gif') - ), - 'KO209i' => array( - 'imagewidth' => 96, 'imageheight' => 96, - 'textwidth' => 8, 'textheight' => 8, - 'color' => 256, - 'imageformats' => array('gif') - ), - 'D210i' => array( - 'imagewidth' => 96, 'imageheight' => 91, - 'textwidth' => 8, 'textheight' => 7, - 'color' => 256, - 'imageformats' => array('gif') - ), - 'F210i' => array( - 'imagewidth' => 96, 'imageheight' => 113, - 'textwidth' => 8, 'textheight' => 8, - 'color' => 256, - 'imageformats' => array('gif') - ), - 'N210i' => array( - 'imagewidth' => 118, 'imageheight' => 113, - 'textwidth' => 10, 'textheight' => 8, - 'color' => 256, - 'imageformats' => array('gif') - ), - 'P210i' => array( - 'imagewidth' => 96, 'imageheight' => 91, - 'textwidth' => 8, 'textheight' => 6, - 'color' => 256, - 'imageformats' => array('gif') - ), - 'KO210i' => array( - 'imagewidth' => 96, 'imageheight' => 96, - 'textwidth' => 8, 'textheight' => 8, - 'color' => 256, - 'imageformats' => array('gif') - ), - 'SO210i' => array( - 'imagewidth' => 120, 'imageheight' => 113, - 'textwidth' => 8, 'textheight' => 7, - 'color' => 256, - 'imageformats' => array('gif') - ), - 'D501i' => array( - 'imagewidth' => 96, 'imageheight' => 72, - 'textwidth' => 8, 'textheight' => 6, - 'color' => 'black', - 'imageformats' => array('gif') - ), - 'F501i' => array( - 'imagewidth' => 112, 'imageheight' => 84, - 'textwidth' => 8, 'textheight' => 6, - 'color' => 'black', - 'imageformats' => array('gif') - ), - 'N501i' => array( - 'imagewidth' => 118, 'imageheight' => 128, - 'textwidth' => 10, 'textheight' =>10, - 'color' => 'black', - 'imageformats' => array('gif') - ), - 'P501i' => array( - 'imagewidth' => 96, 'imageheight' => 120, - 'textwidth' => 8, 'textheight' => 8, - 'color' => 'black', - 'imageformats' => array('gif') - ), - 'D502i' => array( - 'imagewidth' => 96, 'imageheight' => 90, - 'textwidth' => 8, 'textheight' => 7, - 'color' => 256, - 'imageformats' => array('gif') - ), - 'F502i' => array( - 'imagewidth' => 96, 'imageheight' => 91, - 'textwidth' => 8, 'textheight' => 7, - 'color' => 256, - 'imageformats' => array('gif') - ), - 'F502it' => array( - 'imagewidth' => 96, 'imageheight' => 91, - 'textwidth' => 8, 'textheight' => 7, - 'color' => 256, - 'imageformats' => array('gif') - ), - 'N502i' => array( - 'imagewidth' => 118, 'imageheight' => 128, - 'textwidth' => 10, 'textheight' => 10, - 'color' => 'grey', - 'imageformats' => array('gif') - ), - 'N502it' => array( - 'imagewidth' => 118, 'imageheight' => 128, - 'textwidth' => 10, 'textheight' => 10, - 'color' => 256, - 'imageformats' => array('gif') - ), - 'P502i' => array( - 'imagewidth' => 96, 'imageheighth' => 117, - 'textwidth' => 8, 'textheight' => 8, - 'color' => 'grey', - 'imageformats' => array('gif') - ), - 'NM502i' => array( - 'imagewidth' => 111, 'imageheight' => 77, - 'textwidth' => 8, 'textheight' => 6, - 'color' => 'black', - 'imageformats' => array('gif') - ), - 'SO502i' => array( - 'imagewidth' => 120, 'imageheight' => 120, - 'textwidth' => 8, 'textheight' => 8, - 'color' => 'grey', - 'imageformats' => array('gif') - ), - 'SO502iwm' => array( - 'imagewidth' => 120, 'imageheight' => 113, - 'textwidth' => 8, 'textheight' => 7, - 'color' => 256, - 'imageformats' => array('gif') - ), - 'F503i' => array( - 'imagewidth' => 120, 'imageheight' => 130, - 'textwidth' => 10, 'textheight' => 10, - 'color' => 256, - 'imageformats' => array('gif') - ), - 'F503iS' => array( - 'imagewidth' => 120, 'imageheight' => 130, - 'textwidth' => 12, 'textheight' => 12, - 'color' => 4096, - 'imageformats' => array('gif') - ), - 'P503i' => array( - 'imagewidth' => 120, 'imageheight' => 130, - 'textwidth' => 12, 'textheight' => 10, - 'color' => 256, - 'imageformats' => array('gif') - ), - 'P503iS' => array( - 'imagewidth' => 120, 'imageheight' => 130, - 'textwidth' => 12, 'textheight' => 10, - 'color' => 256, - 'imageformats' => array('gif') - ), - 'SO503i' => array( - 'imagewidth' => 120, 'imageheight' => 113, - 'textwidth' => 8.5, 'textheight' => 7, - 'color' => 65536, - 'imageformats' => array('gif') - ), - 'D503i' => array( - 'imagewidth' => 132, 'imageheight' => 126, - 'textwidth' => 8, 'textheight' => 7, - 'color' => 4096, - 'imageformats' => array('gif') - ), - 'N503i' => array( - 'imagewidth' => 118, 'imageheight' => 128, - 'textwidth' => 10, 'textheight' => 10, - 'color' => 4096, - 'imageformats' => array('gif', 'jpg') - ), - 'N503iS' => array( - 'imagewidth' => 118, 'imageheight' => 128, - 'textwidth' => 10, 'textheight' => 10, - 'color' => 4096, - 'imageformats' => array('gif', 'jpg') - ), - 'N691i' => array( - 'imagewidth' => 96, 'imageheight' => 72, - 'textwidth' => 8, 'textheight' => 6, - 'color' => 'grey', - 'imageformats' => array('gif') - ), - 'SH821i' => array( - 'imagewidth' => 96, 'imageheight' => 78, - 'textwidth' => 8, 'textheight' => 6, - 'color' => 256, - 'imageformats' => array('gif') - ), - 'N821i' => array( - 'imagewidth' => 118, 'imageheight' => 128, - 'textwidth' => 10, 'textheight' => 10, - 'color' => 'grey', - 'imageformats' => array('gif') - ), - 'P821i' => array( - 'imagewidth' => 118, 'imageheight' => 128, - 'textwidth' => 10, 'textheight' => 10, - 'color' => 'grey', - 'imageformats' => array('gif') - ), - 'safe' => array( - 'imagewidth' => 94, 'imageheight' => 72, - 'textwidth' => 8, 'textheight' => 6, - 'color' => 'black', - 'imageformats' => array('gif') - ) - ); - - var $_manufacturerlist = array( - 'D' => 'Mitsubishi', - 'P' => 'Panasonic (Matsushita)', - 'NM' => 'Nokia', - 'SO' => 'Sony', - 'F' => 'Fujitsu', - 'N' => 'Nec', - 'SH' => 'Sharp', - 'ER' => 'Ericsson', - 'R' => 'Japan Radio', - 'KO' => 'Kokusai (Hitachi)' - ); - - var $_extra = array( - 't' => 'Transport layer', - 'e' => 'English language', - 's' => 'Second version' - ); - - var $_user_agent; - var $_model; - var $_manufacturer; - var $_httpversion; - var $_cache = 5; - - /** - * Does not handle bogus user_agents or most of the other error - * situation properly yet. - * - * Example usage: - * $ua = new Browser_imode($_SERVEr['HTTP_USER_AGENT']); - * - * @param string $input The user agent to match. - */ - function Browser_imode($input) - { - $_error = 0; - $temp = explode('/', $input); - - $this->_user_agent = $input; - $this->_httpversion = $temp[1]; - $this->_model = $temp[2]; - if ($temp[3]) { - $this->_cache = substr($temp[3], 1); - } - - preg_match('/(^[a-zA-Z]+)([0-9]+i)(.*)\/?(.*)/', $this->_model, $matches); - - // @TODO: Fix situation of unknown manufacturer. Implement - // extrainfo properly. - $this->_manufacturer = $this->_manufacturerlist[$matches[1]]; - $this->_extra = $matches[3]; - - if (!($this->_data[$this->_model])) { - $_error = PEAR::raiseError('Unknown User Agent'); - } - } - - /** - * Example usage: - * $imagedim = $ua->getImageDimensions(); - * $imagewidth = $imagedim[0]; - * $imageheight = $imagedim[1]; - * - * @return array The maximum imagewidth and imageheight that - * fit on the handset screen without scrolling. - */ - function getImageDimensions() - { - $data = $this->_data[$this->_model]; - return array($data['imagewidth'], $data['imageheight']); - } - - /** - * Example usage: - * $textdim = $ua->getTextDimensions(); - * $textwidth = $textdim[0]; - * $textheight = $textdim[1]; - * - * @return array The Maximum textwidth and textheight that - * fit on the handset screen without scrolling. - */ - function getTextDimensions() - { - return array($this->_data[$this->_model]['textwidth'], - $this->_data[$this->_model]['textheight']); - } - - /** - * @return integer The amount of handset cache in kilobytes. - */ - function getCache() - { - return (int)$this->_cache; - } - - function getManufacturer() - { - return $this->_manufacturer; - } - - function getExtra() - { - return $this->_extra; - } - - function getImageFormats() - { - return $this->_data[$this->_model]['imageformats']; - } - - /** - * @return integer Which color model the handset supports. - * Values have the following meaning: - * 0 -> black and white - * 1 -> 4 tone greyscale - * 2 -> 256 color - */ - function getColor() - { - return $this->_data[$this->_model]['color']; - } - - function getHTTPVersion() - { - return $this->_httpversion; - } - - function isColor() - { - return $this->_data[$this->_model]['color'] == 256; - } - - function isGreyScale() - { - return $this->_data[$this->_model]['color'] == 'grey'; - } - - function isBlackAndWhite() - { - return $this->_data[$this->_model]['color'] == 'black'; - } - -} diff --git a/phpgwapi/inc/horde/Horde/Date.php b/phpgwapi/inc/horde/Horde/Date.php deleted file mode 100644 index 496a2ca328..0000000000 --- a/phpgwapi/inc/horde/Horde/Date.php +++ /dev/null @@ -1,769 +0,0 @@ -_supportedSpecs .= 'bBpxX'; - } - - if (is_array($date) || is_object($date)) { - foreach ($date as $key => $val) { - if (in_array($key, array('year', 'month', 'mday', 'hour', 'min', 'sec'))) { - $this->$key = (int)$val; - } - } - - // If $date['day'] is present and numeric we may have been passed - // a Horde_Form_datetime array. - if (is_array($date) && isset($date['day']) && - is_numeric($date['day'])) { - $this->mday = (int)$date['day']; - } - // 'minute' key also from Horde_Form_datetime - if (is_array($date) && isset($date['minute'])) { - $this->min = $date['minute']; - } - } elseif (!is_null($date)) { - // Match YYYY-MM-DD HH:MM:SS, YYYYMMDDHHMMSS and YYYYMMDD'T'HHMMSS'Z'. - if (preg_match('/(\d{4})-?(\d{2})-?(\d{2})T? ?(\d{2}):?(\d{2}):?(\d{2})Z?/', $date, $parts)) { - $this->year = (int)$parts[1]; - $this->month = (int)$parts[2]; - $this->mday = (int)$parts[3]; - $this->hour = (int)$parts[4]; - $this->min = (int)$parts[5]; - $this->sec = (int)$parts[6]; - } else { - // Try as a timestamp. - $parts = @getdate($date); - if ($parts) { - $this->year = $parts['year']; - $this->month = $parts['mon']; - $this->mday = $parts['mday']; - $this->hour = $parts['hours']; - $this->min = $parts['minutes']; - $this->sec = $parts['seconds']; - } - } - } - } - - /** - * @static - */ - function isLeapYear($year) - { - if (strlen($year) != 4 || preg_match('/\D/', $year)) { - return false; - } - - return (($year % 4 == 0 && $year % 100 != 0) || $year % 400 == 0); - } - - /** - * Returns the day of the year (1-366) that corresponds to the - * first day of the given week. - * - * TODO: with PHP 5.1+, see http://derickrethans.nl/calculating_start_and_end_dates_of_a_week.php - * - * @param integer $week The week of the year to find the first day of. - * @param integer $year The year to calculate for. - * - * @return integer The day of the year of the first day of the given week. - */ - function firstDayOfWeek($week, $year) - { - $jan1 = new Horde_Date(array('year' => $year, 'month' => 1, 'mday' => 1)); - $start = $jan1->dayOfWeek(); - if ($start > HORDE_DATE_THURSDAY) { - $start -= 7; - } - return (($week * 7) - (7 + $start)) + 1; - } - - /** - * @static - */ - function daysInMonth($month, $year) - { - if ($month == 2) { - if (Horde_Date::isLeapYear($year)) { - return 29; - } else { - return 28; - } - } elseif ($month == 4 || $month == 6 || $month == 9 || $month == 11) { - return 30; - } else { - return 31; - } - } - - /** - * Return the day of the week (0 = Sunday, 6 = Saturday) of this - * object's date. - * - * @return integer The day of the week. - */ - function dayOfWeek() - { - if ($this->month > 2) { - $month = $this->month - 2; - $year = $this->year; - } else { - $month = $this->month + 10; - $year = $this->year - 1; - } - - $day = (floor((13 * $month - 1) / 5) + - $this->mday + ($year % 100) + - floor(($year % 100) / 4) + - floor(($year / 100) / 4) - 2 * - floor($year / 100) + 77); - - return (int)($day - 7 * floor($day / 7)); - } - - /** - * Returns the day number of the year (1 to 365/366). - * - * @return integer The day of the year. - */ - function dayOfYear() - { - $monthTotals = array(0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334); - $dayOfYear = $this->mday + $monthTotals[$this->month - 1]; - if (Horde_Date::isLeapYear($this->year) && $this->month > 2) { - ++$dayOfYear; - } - - return $dayOfYear; - } - - /** - * Returns the week of the month. - * - * @since Horde 3.2 - * - * @return integer The week number. - */ - function weekOfMonth() - { - return ceil($this->mday / 7); - } - - /** - * Returns the week of the year, first Monday is first day of first week. - * - * @return integer The week number. - */ - function weekOfYear() - { - return $this->format('W'); - } - - /** - * Return the number of weeks in the given year (52 or 53). - * - * @static - * - * @param integer $year The year to count the number of weeks in. - * - * @return integer $numWeeks The number of weeks in $year. - */ - function weeksInYear($year) - { - // Find the last Thursday of the year. - $day = 31; - $date = new Horde_Date(array('year' => $year, 'month' => 12, 'mday' => $day, 'hour' => 0, 'min' => 0, 'sec' => 0)); - while ($date->dayOfWeek() != HORDE_DATE_THURSDAY) { - --$date->mday; - } - return $date->weekOfYear(); - } - - /** - * Set the date of this object to the $nth weekday of $weekday. - * - * @param integer $weekday The day of the week (0 = Sunday, etc). - * @param integer $nth The $nth $weekday to set to (defaults to 1). - */ - function setNthWeekday($weekday, $nth = 1) - { - if ($weekday < HORDE_DATE_SUNDAY || $weekday > HORDE_DATE_SATURDAY) { - return false; - } - - $this->mday = 1; - $first = $this->dayOfWeek(); - if ($weekday < $first) { - $this->mday = 8 + $weekday - $first; - } else { - $this->mday = $weekday - $first + 1; - } - $this->mday += 7 * $nth - 7; - - $this->correct(); - - return true; - } - - function dump($prefix = '') - { - echo ($prefix ? $prefix . ': ' : '') . $this->year . '-' . $this->month . '-' . $this->mday . "
\n"; - } - - /** - * Is the date currently represented by this object a valid date? - * - * @return boolean Validity, counting leap years, etc. - */ - function isValid() - { - if ($this->year < 0 || $this->year > 9999) { - return false; - } - return checkdate($this->month, $this->mday, $this->year); - } - - /** - * Correct any over- or underflows in any of the date's members. - * - * @param integer $mask We may not want to correct some overflows. - */ - function correct($mask = HORDE_DATE_MASK_ALLPARTS) - { - if ($mask & HORDE_DATE_MASK_SECOND) { - while ($this->sec < 0) { - --$this->min; - $this->sec += 60; - } - while ($this->sec > 59) { - ++$this->min; - $this->sec -= 60; - } - } - - if ($mask & HORDE_DATE_MASK_MINUTE) { - while ($this->min < 0) { - --$this->hour; - $this->min += 60; - } - while ($this->min > 59) { - ++$this->hour; - $this->min -= 60; - } - } - - if ($mask & HORDE_DATE_MASK_HOUR) { - while ($this->hour < 0) { - --$this->mday; - $this->hour += 24; - } - while ($this->hour > 23) { - ++$this->mday; - $this->hour -= 24; - } - } - - if ($mask & HORDE_DATE_MASK_MONTH) { - while ($this->month > 12) { - ++$this->year; - $this->month -= 12; - } - while ($this->month < 1) { - --$this->year; - $this->month += 12; - } - } - - if ($mask & HORDE_DATE_MASK_DAY) { - while ($this->mday > Horde_Date::daysInMonth($this->month, $this->year)) { - $this->mday -= Horde_Date::daysInMonth($this->month, $this->year); - ++$this->month; - $this->correct(HORDE_DATE_MASK_MONTH); - } - while ($this->mday < 1) { - --$this->month; - $this->correct(HORDE_DATE_MASK_MONTH); - $this->mday += Horde_Date::daysInMonth($this->month, $this->year); - } - } - } - - /** - * Compare this date to another date object to see which one is - * greater (later). Assumes that the dates are in the same - * timezone. - * - * @param mixed $date The date to compare to. - * - * @return integer == 0 if the dates are equal - * >= 1 if this date is greater (later) - * <= -1 if the other date is greater (later) - */ - function compareDate($date) - { - if (!is_a($date, 'Horde_Date')) { - $date = new Horde_Date($date); - } - - if ($this->year != $date->year) { - return $this->year - $date->year; - } - if ($this->month != $date->month) { - return $this->month - $date->month; - } - - return $this->mday - $date->mday; - } - - /** - * Compare this to another date object by time, to see which one - * is greater (later). Assumes that the dates are in the same - * timezone. - * - * @param mixed $date The date to compare to. - * - * @return integer == 0 if the dates are equal - * >= 1 if this date is greater (later) - * <= -1 if the other date is greater (later) - */ - function compareTime($date) - { - if (!is_a($date, 'Horde_Date')) { - $date = new Horde_Date($date); - } - - if ($this->hour != $date->hour) { - return $this->hour - $date->hour; - } - if ($this->min != $date->min) { - return $this->min - $date->min; - } - - return $this->sec - $date->sec; - } - - /** - * Compare this to another date object, including times, to see - * which one is greater (later). Assumes that the dates are in the - * same timezone. - * - * @param mixed $date The date to compare to. - * - * @return integer == 0 if the dates are equal - * >= 1 if this date is greater (later) - * <= -1 if the other date is greater (later) - */ - function compareDateTime($date) - { - if (!is_a($date, 'Horde_Date')) { - $date = new Horde_Date($date); - } - - if ($diff = $this->compareDate($date)) { - return $diff; - } - - return $this->compareTime($date); - } - - /** - * Get the time offset for local time zone. - * - * @param boolean $colon Place a colon between hours and minutes? - * - * @return string Timezone offset as a string in the format +HH:MM. - */ - function tzOffset($colon = true) - { - $secs = $this->format('Z'); - - if ($secs < 0) { - $sign = '-'; - $secs = -$secs; - } else { - $sign = '+'; - } - $colon = $colon ? ':' : ''; - $mins = intval(($secs + 30) / 60); - return sprintf('%s%02d%s%02d', - $sign, $mins / 60, $colon, $mins % 60); - } - - /** - * Return the unix timestamp representation of this date. - * - * @return integer A unix timestamp. - */ - function timestamp() - { - if (class_exists('DateTime')) { - return $this->format('U'); - } else { - return Horde_Date::_mktime($this->hour, $this->min, $this->sec, $this->month, $this->mday, $this->year); - } - } - - /** - * Return the unix timestamp representation of this date, 12:00am. - * - * @return integer A unix timestamp. - */ - function datestamp() - { - if (class_exists('DateTime')) { - $dt = new DateTime(); - $dt->setDate($this->year, $this->month, $this->mday); - $dt->setTime(0, 0, 0); - return $dt->format('U'); - } else { - return Horde_Date::_mktime(0, 0, 0, $this->month, $this->mday, $this->year); - } - } - - /** - * Format time using the specifiers available in date() or in the DateTime - * class' format() method. - * - * @since Horde 3.3 - * - * @param string $format - * - * @return string Formatted time. - */ - function format($format) - { - if (class_exists('DateTime')) { - $dt = new DateTime(); - $dt->setDate($this->year, $this->month, $this->mday); - $dt->setTime($this->hour, $this->min, $this->sec); - return $dt->format($format); - } else { - return date($format, $this->timestamp()); - } - } - - /** - * Format time in ISO-8601 format. Works correctly since Horde 3.2. - * - * @return string Date and time in ISO-8601 format. - */ - function iso8601DateTime() - { - return $this->rfc3339DateTime() . $this->tzOffset(); - } - - /** - * Format time in RFC 2822 format. - * - * @return string Date and time in RFC 2822 format. - */ - function rfc2822DateTime() - { - return $this->format('D, j M Y H:i:s') . ' ' . $this->tzOffset(false); - } - - /** - * Format time in RFC 3339 format. - * - * @since Horde 3.1 - * - * @return string Date and time in RFC 3339 format. The seconds part has - * been added with Horde 3.2. - */ - function rfc3339DateTime() - { - return $this->format('Y-m-d\TH:i:s'); - } - - /** - * Format time to standard 'ctime' format. - * - * @return string Date and time. - */ - function cTime() - { - return $this->format('D M j H:i:s Y'); - } - - /** - * Format date and time using strftime() format. - * - * @since Horde 3.1 - * - * @return string strftime() formatted date and time. - */ - function strftime($format) - { - if (preg_match('/%[^' . $this->_supportedSpecs . ']/', $format)) { - return strftime($format, $this->timestamp()); - } else { - return $this->_strftime($format); - } - } - - /** - * Format date and time using a limited set of the strftime() format. - * - * @return string strftime() formatted date and time. - */ - function _strftime($format) - { - if (preg_match('/%[bBpxX]/', $format)) { - require_once 'Horde/NLS.php'; - } - - return preg_replace( - array('/%b/e', - '/%B/e', - '/%C/e', - '/%d/e', - '/%D/e', - '/%e/e', - '/%H/e', - '/%I/e', - '/%m/e', - '/%M/e', - '/%n/', - '/%p/e', - '/%R/e', - '/%S/e', - '/%t/', - '/%T/e', - '/%x/e', - '/%X/e', - '/%y/e', - '/%Y/', - '/%%/'), - array('$this->_strftime(NLS::getLangInfo(constant(\'ABMON_\' . (int)$this->month)))', - '$this->_strftime(NLS::getLangInfo(constant(\'MON_\' . (int)$this->month)))', - '(int)($this->year / 100)', - 'sprintf(\'%02d\', $this->mday)', - '$this->_strftime(\'%m/%d/%y\')', - 'sprintf(\'%2d\', $this->mday)', - 'sprintf(\'%02d\', $this->hour)', - 'sprintf(\'%02d\', $this->hour == 0 ? 12 : ($this->hour > 12 ? $this->hour - 12 : $this->hour))', - 'sprintf(\'%02d\', $this->month)', - 'sprintf(\'%02d\', $this->min)', - "\n", - '$this->_strftime(NLS::getLangInfo($this->hour < 12 ? AM_STR : PM_STR))', - '$this->_strftime(\'%H:%M\')', - 'sprintf(\'%02d\', $this->sec)', - "\t", - '$this->_strftime(\'%H:%M:%S\')', - '$this->_strftime(NLS::getLangInfo(D_FMT))', - '$this->_strftime(NLS::getLangInfo(T_FMT))', - 'substr(sprintf(\'%04d\', $this->year), -2)', - (int)$this->year, - '%'), - $format); - } - - /** - * mktime() implementation that supports dates outside of 1970-2038, - * from http://phplens.com/phpeverywhere/adodb_date_library. - * - * @TODO remove in Horde 4 - * - * This does NOT work with pre-1970 daylight saving times. - * - * @static - */ - function _mktime($hr, $min, $sec, $mon = false, $day = false, - $year = false, $is_dst = false, $is_gmt = false) - { - if ($mon === false) { - return $is_gmt - ? @gmmktime($hr, $min, $sec) - : @mktime($hr, $min, $sec); - } - - if ($year > 1901 && $year < 2038 && - ($year >= 1970 || version_compare(PHP_VERSION, '5.0.0', '>='))) { - return $is_gmt - ? @gmmktime($hr, $min, $sec, $mon, $day, $year) - : @mktime($hr, $min, $sec, $mon, $day, $year); - } - - $gmt_different = $is_gmt - ? 0 - : (mktime(0, 0, 0, 1, 2, 1970, 0) - gmmktime(0, 0, 0, 1, 2, 1970, 0)); - - $mon = intval($mon); - $day = intval($day); - $year = intval($year); - - if ($mon > 12) { - $y = floor($mon / 12); - $year += $y; - $mon -= $y * 12; - } elseif ($mon < 1) { - $y = ceil((1 - $mon) / 12); - $year -= $y; - $mon += $y * 12; - } - - $_day_power = 86400; - $_hour_power = 3600; - $_min_power = 60; - - $_month_table_normal = array('', 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31); - $_month_table_leaf = array('', 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31); - - $_total_date = 0; - if ($year >= 1970) { - for ($a = 1970; $a <= $year; $a++) { - $leaf = Horde_Date::isLeapYear($a); - if ($leaf == true) { - $loop_table = $_month_table_leaf; - $_add_date = 366; - } else { - $loop_table = $_month_table_normal; - $_add_date = 365; - } - if ($a < $year) { - $_total_date += $_add_date; - } else { - for ($b = 1; $b < $mon; $b++) { - $_total_date += $loop_table[$b]; - } - } - } - - return ($_total_date + $day - 1) * $_day_power + $hr * $_hour_power + $min * $_min_power + $sec + $gmt_different; - } - - for ($a = 1969 ; $a >= $year; $a--) { - $leaf = Horde_Date::isLeapYear($a); - if ($leaf == true) { - $loop_table = $_month_table_leaf; - $_add_date = 366; - } else { - $loop_table = $_month_table_normal; - $_add_date = 365; - } - if ($a > $year) { - $_total_date += $_add_date; - } else { - for ($b = 12; $b > $mon; $b--) { - $_total_date += $loop_table[$b]; - } - } - } - - $_total_date += $loop_table[$mon] - $day; - $_day_time = $hr * $_hour_power + $min * $_min_power + $sec; - $_day_time = $_day_power - $_day_time; - $ret = -($_total_date * $_day_power + $_day_time - $gmt_different); - if ($ret < -12220185600) { - // If earlier than 5 Oct 1582 - gregorian correction. - return $ret + 10 * 86400; - } elseif ($ret < -12219321600) { - // If in limbo, reset to 15 Oct 1582. - return -12219321600; - } else { - return $ret; - } - } - -} diff --git a/phpgwapi/inc/horde/Horde/NLS.php b/phpgwapi/inc/horde/Horde/NLS.php deleted file mode 100644 index c96b801e6b..0000000000 --- a/phpgwapi/inc/horde/Horde/NLS.php +++ /dev/null @@ -1,523 +0,0 @@ -country lookups. - * - * $Horde: framework/NLS/NLS.php,v 1.86 2005/02/28 15:45:56 jan Exp $ - * - * Copyright 1999-2005 Jon Parise - * Copyright 1999-2005 Chuck Hagenbuch - * Copyright 2002-2005 Jan Schneider - * Copyright 2003-2005 Michael Slusarz - * - * 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 Jon Parise - * @author Chuck Hagenbuch - * @author Jan Schneider - * @author Michael Slusarz - * @version $Revision$ - * @since Horde 3.0 - * @package Horde_NLS - */ -class NLS { - - /** - * Selects the most preferred language for the current client session. - * - * @access public - * - * @return string The selected language abbreviation. - */ - function select() - { - global $nls, $prefs; - - $lang = Util::getFormData('new_lang'); - - /* First, check if language pref is locked and, if so, set it to its - value */ - if (isset($prefs) && $prefs->isLocked('language')) { - $language = $prefs->getValue('language'); - /* Check if the user selected a language from the login screen */ - } elseif (!empty($lang)) { - $language = $lang; - /* Check if we have a language set in a cookie */ - } elseif (isset($_SESSION['horde_language'])) { - $language = $_SESSION['horde_language']; - /* Use site-wide default, if one is defined */ - } elseif (!empty($nls['defaults']['language'])) { - $language = $nls['defaults']['language']; - /* Try browser-accepted languages. */ - } elseif (!empty($_SERVER['HTTP_ACCEPT_LANGUAGE'])) { - /* The browser supplies a list, so return the first valid one. */ - $browser_langs = explode(',', $_SERVER['HTTP_ACCEPT_LANGUAGE']); - foreach ($browser_langs as $lang) { - /* Strip quality value for language */ - if (($pos = strpos($lang, ';')) !== false) { - $lang = substr($lang, 0, $pos); - } - $lang = NLS::_map(trim($lang)); - if (NLS::isValid($lang)) { - $language = $lang; - break; - } - /* In case no full match, save best guess based on prefix */ - if (!isset($partial_lang) && - NLS::isValid(NLS::_map(substr($lang, 0, 2)))) { - $partial_lang = NLS::_map(substr($lang, 0, 2)); - } - } - } - - if (!isset($language)) { - if (isset($partial_lang)) { - $language = $partial_lang; - } else { - /* No dice auto-detecting, default to US English. */ - $language = 'en_US'; - } - } - - return basename($language); - } - - /** - * Sets the language. - * - * @access public - * - * @param optional string $lang The language abbriviation. - */ - function setLang($lang = null) - { - include_once HORDE_BASE . '/config/nls.php'; - - if (empty($lang) || !NLS::isValid($lang)) { - $lang = NLS::select(); - } - - if (isset($GLOBALS['language']) && $GLOBALS['language'] == $lang) { - return; - } - - $GLOBALS['language'] = $lang; - - /* First try language with the current charset. */ - $lang_charset = $lang . '.' . NLS::getCharset(); - if ($lang_charset != setlocale(LC_ALL, $lang_charset)) { - /* Next try language with its default charset. */ - global $nls; - $charset = !empty($nls['charsets'][$lang]) ? $nls['charsets'][$lang] : $nls['defaults']['charset']; - $lang_charset = $lang . '.' . $charset; - NLS::_cachedCharset(0, $charset); - if ($lang_charset != setlocale(LC_ALL, $lang_charset)) { - /* At last try language solely. */ - $lang_charset = $lang; - setlocale(LC_ALL, $lang_charset); - } - } - @putenv('LANG=' . $lang_charset); - @putenv('LANGUAGE=' . $lang_charset); - } - - /** - * Sets the gettext domain. - * - * @access public - * - * @param string $app The application name. - * @param string $directory The directory where the application's - * LC_MESSAGES directory resides. - * @param string $charset The charset. - */ - function setTextdomain($app, $directory, $charset) - { - bindtextdomain($app, $directory); - textdomain($app); - - /* The existence of this function depends on the platform. */ - if (function_exists('bind_textdomain_codeset')) { - NLS::_cachedCharset(0, bind_textdomain_codeset($app, $charset)); - } - - if (!headers_sent()) { - header('Content-Type: text/html; charset=' . $charset); - } - } - - /** - * Determines whether the supplied language is valid. - * - * @access public - * - * @param string $language The abbreviated name of the language. - * - * @return boolean True if the language is valid, false if it's not - * valid or unknown. - */ - function isValid($language) - { - return !empty($GLOBALS['nls']['languages'][$language]); - } - - /** - * Maps languages with common two-letter codes (such as nl) to the - * full gettext code (in this case, nl_NL). Returns the language - * unmodified if it isn't an alias. - * - * @access private - * - * @param string $language The language code to map. - * - * @return string The mapped language code. - */ - - function _map($language) - { - require_once 'Horde/String.php'; - - $aliases = &$GLOBALS['nls']['aliases']; - - // Translate the $language to get broader matches. - // (eg. de-DE should match de_DE) - $trans_lang = str_replace('-', '_', $language); - $lang_parts = explode('_', $trans_lang); - $trans_lang = String::lower($lang_parts[0]); - if (isset($lang_parts[1])) { - $trans_lang .= '_' . String::upper($lang_parts[1]); - } - - // See if we get a match for this - if (!empty($aliases[$trans_lang])) { - return $aliases[$trans_lang]; - } - - // If we get that far down, the language cannot be found. - // Return $trans_lang. - return $trans_lang; - } - - /** - * Returns the charset for the current language. - * - * @access public - * - * @param boolean $original If true returns the original charset of the - * translation, the actually used one otherwise. - * - * @return string The character set that should be used with the current - * locale settings. - */ - function getCharset($original = false) - { - global $language, $nls; - - /* Get cached results. */ - $cacheKey = intval($original); - $charset = NLS::_cachedCharset($cacheKey); - if (!is_null($charset)) { - return $charset; - } - - if ($original) { - $charset = empty($nls['charsets'][$language]) ? $nls['defaults']['charset'] : $nls['charsets'][$language]; - } else { - require_once 'Horde/Browser.php'; - $browser = &Browser::singleton(); - - if ($browser->hasFeature('utf') && - (Util::extensionExists('iconv') || - Util::extensionExists('mbstring'))) { - $charset = 'UTF-8'; - } - } - - if (is_null($charset)) { - $charset = NLS::getExternalCharset(); - } - - NLS::_cachedCharset($cacheKey, $charset); - return $charset; - } - - - /** - * Returns the current charset of the environment - * - * @access public - * - * @return string The character set that should be used with the current - * locale settings. - */ - function getExternalCharset() - { - global $language, $nls; - - /* Get cached results. */ - $charset = NLS::_cachedCharset(2); - if (!is_null($charset)) { - return $charset; - } - - $lang_charset = setlocale(LC_ALL, 0); - if (strpos($lang_charset, ';') === false && - strpos($lang_charset, '/') === false) { - $lang_charset = explode('.', $lang_charset); - if ((count($lang_charset) == 2) && !empty($lang_charset[1])) { - NLS::_cachedCharset(2, $lang_charset[1]); - return $lang_charset[1]; - } - } - - return (!empty($nls['charsets'][$language])) ? $nls['charsets'][$language] : $nls['defaults']['charset']; - } - - /** - * Sets or returns the charset used under certain conditions. - * - * @access private - * - * @param integer $index The ID of a cache slot. 0 for the UI charset, 1 - * for the translation charset and 2 for the - * external charset. - * @param string $charset If specified, this charset will be stored in the - * given cache slot. Otherwise the content of the - * specified cache slot will be returned. - */ - function _cachedCharset($index, $charset = null) - { - static $cache; - - if (!isset($cache)) { - $cache = array(); - } - - if ($charset == null) { - return isset($cache[$index]) ? $cache[$index] : null; - } else { - $cache[$index] = $charset; - } - } - - /** - * Returns the charset to use for outgoing emails. - * - * @return string The preferred charset for outgoing mails based on - * the user's preferences and the current language. - */ - function getEmailCharset() - { - global $prefs, $language, $nls; - - $charset = $prefs->getValue('sending_charset'); - if (!empty($charset)) { - return $charset; - } - return isset($nls['emails'][$language]) ? $nls['emails'][$language] : - (isset($nls['charsets'][$language]) ? $nls['charsets'][$language] : $nls['defaults']['charset']); - } - - /** - * Check to see if character set is valid for htmlspecialchars() calls. - * - * @access public - * - * @param string $charset The character set to check. - * - * @return boolean Is charset valid for the current system? - */ - function checkCharset($charset) - { - static $check; - - if (is_null($charset) || empty($charset)) { - return false; - } - - if (isset($check[$charset])) { - return $check[$charset]; - } elseif (!isset($check)) { - $check = array(); - } - - $valid = true; - - ini_set('track_errors', 1); - @htmlspecialchars('', ENT_COMPAT, $charset); - if (isset($php_errormsg)) { - $valid = false; - } - ini_restore('track_errors'); - - $check[$charset] = $valid; - - return $valid; - } - - /** - * Sets the current timezone, if available. - * - * @access public - */ - function setTimeZone() - { - global $prefs; - - $tz = $prefs->getValue('timezone'); - if (!empty($tz)) { - @putenv('TZ=' . $tz); - } - } - - /** - * Get the locale info returned by localeconv(), but cache it, to - * avoid repeated calls. - * - * @access public - * - * @return array The results of localeconv(). - */ - function getLocaleInfo() - { - static $lc_info; - - if (!isset($lc_info)) { - $lc_info = localeconv(); - } - - return $lc_info; - } - - /** - * Get the language info returned by nl_langinfo(), but cache it, to - * avoid repeated calls. - * - * @access public - * @since Horde 3.1 - * - * @param const $item The langinfo item to return. - * - * @return array The results of nl_langinfo(). - */ - function getLangInfo($item) - { - static $nl_info = array(); - - if (!isset($nl_info[$item])) { - $nl_info[$item] = nl_langinfo($item); - } - - return $nl_info[$item]; - } - - /** - * Get country information from a hostname or IP address. - * - * @access public - * - * @param string $host The hostname or IP address. - * - * @return mixed On success, return an array with the following entries: - * 'code' => Country Code - * 'name' => Country Name - * On failure, return false. - */ - function getCountryByHost($host) - { - global $conf; - - /* List of generic domains that we know is not in the country TLD - list. See: http://www.iana.org/gtld/gtld.htm */ - $generic = array( - 'aero', 'biz', 'com', 'coop', 'edu', 'gov', 'info', 'int', 'mil', - 'museum', 'name', 'net', 'org', 'pro' - ); - - $checkHost = $host; - if (preg_match('/^\d+\.\d+\.\d+\.\d+$/', $host)) { - $checkHost = @gethostbyaddr($host); - } - - /* Get the TLD of the hostname. */ - $pos = strrpos($checkHost, '.'); - if ($pos === false) { - return false; - } - $domain = String::lower(substr($checkHost, $pos + 1)); - - /* Try lookup via TLD first. */ - if (!in_array($domain, $generic)) { - require 'Horde/NLS/tld.php'; - if (isset($tld[$domain])) { - return array('code' => $domain, 'name' => $tld[$domain]); - } - } - - /* Try GeoIP lookup next. */ - if (!empty($conf['geoip']['datafile'])) { - require_once 'Horde/NLS/GeoIP.php'; - $geoip = &NLS_GeoIP::singleton($conf['geoip']['datafile']); - $id = $geoip->countryIdByName($checkHost); - if (!empty($id)) { - return array('code' => String::lower($GLOBALS['GEOIP_COUNTRY_CODES'][$id]), 'name' => $GLOBALS['GEOIP_COUNTRY_NAMES'][$id]); - } - } - - return false; - } - - /** - * Returns a Horde image link to the country flag. - * - * @access public - * - * @param string $host The hostname or IP address. - * - * @return string The image URL, or the empty string on error. - */ - function generateFlagImageByHost($host) - { - global $registry; - - $data = NLS::getCountryByHost($host); - if ($data !== false) { - $img = $data['code'] . '.png'; - if (file_exists($registry->get('themesfs', 'horde') . '/graphics/flags/' . $img)) { - return Horde::img($img, $data['name'], '', $registry->getImageDir('horde') . '/flags'); - } else { - return '[' . $data['name'] . ']'; - } - } - - return ''; - } - - /** - * Returns either a specific or all ISO-3166 country names. - * - * @access public - * - * @param optional string $code The ISO 3166 country code. - * - * @return mixed If a country code has been requested will return the - * corresponding country name. If empty will return an - * array of all the country codes and their names. - */ - function &getCountryISO($code = '') - { - static $countries = array(); - if (empty($countries)) { - require_once 'Horde/NLS/countries.php'; - } - if (empty($code)) { - return $countries; - } elseif (isset($countries[$code])) { - return $countries[$code]; - } - return false; - } - -} diff --git a/phpgwapi/inc/horde/Horde/RPC.php b/phpgwapi/inc/horde/Horde/RPC.php deleted file mode 100644 index 4f01799312..0000000000 --- a/phpgwapi/inc/horde/Horde/RPC.php +++ /dev/null @@ -1,252 +0,0 @@ - - * $response = Horde_RPC::request('xmlrpc', - * 'http://localhost:80/horde/rpc.php' - * 'contacts.search', - * array(array('jan'), array('localsql'), - * array('name', 'email')), - * array('user' => Auth::getAuth(), - * 'pass' => Auth::getCredential('password'))); - * - * - * $Horde: framework/RPC/RPC.php,v 1.14 2006/01/01 21:10:10 jan Exp $ - * - * Copyright 2002-2006 Jan Schneider - * - * 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 - * @since Horde 3.0 - * @package Horde_RPC - */ -class Horde_RPC { - - /** - * Whether we need an authorized user or not. - * - * @access protected - * @var boolean - */ - var $_authorize = true; - - /** - * RPC server constructor - * - * @access private - * @return object An RPC server instance. - */ - function Horde_RPC() - { - register_shutdown_function(array($this, 'shutdown')); - } - - /** - * Cleans up the RPC server. - * - * @abstract - */ - function shutdown() - { - } - - /** - * Check authentication. Different backends may handle - * authentication in different ways. The base class implementation - * checks for HTTP Authentication against the Horde auth setup. - * - * @return boolean Returns true if authentication is successful. - * Should send appropriate "not authorized" headers - * or other response codes/body if auth fails, - * and take care of exiting. - */ - function authorize() - { - if (!$this->_authorize) { - return true; - } - - $auth = &Auth::singleton($GLOBALS['conf']['auth']['driver']); - - if (isset($_SERVER['PHP_AUTH_USER'])) { - $user = $_SERVER['PHP_AUTH_USER']; - $pass = $_SERVER['PHP_AUTH_PW']; - } - - if (!isset($user) - || !$auth->authenticate($user, array('password' => $pass))) { - header('WWW-Authenticate: Basic realm="Horde RPC"'); - header('HTTP/1.0 401 Unauthorized'); - echo '401 Unauthorized'; - exit; - } - - return true; - } - - /** - * Get the request body input. Different RPC backends can override - * this to return an open stream to php://stdin, for instance - - * whatever is easiest to handle in the getResponse() method. - * - * The base class implementation looks for $HTTP_RAW_POST_DATA and - * returns that if it's available; otherwise, it returns the - * contents of php://stdin. - * - * @return mixed The input - a string (default), a filehandle, etc. - */ - function getInput() - { - if (isset($GLOBALS['HTTP_RAW_POST_DATA'])) { - return $GLOBALS['HTTP_RAW_POST_DATA']; - } else { - return implode("\r\n", file('php://input')); - } - } - - /** - * Sends an RPC request to the server and returns the result. - * - * @param string The raw request string. - * - * @return string The XML encoded response from the server. - */ - function getResponse($request) - { - return _("not implemented"); - } - - /** - * Get the Content-Type of the response. - * - * @return string The MIME Content-Type of the RPC response. - */ - function getResponseContentType() - { - return 'text/xml'; - } - - /** - * Builds an RPC request and sends it to the RPC server. - * - * This statically called method is actually the RPC client. - * - * @param string $driver The protocol driver to use. Currently 'soap' - * and 'xmlrpc' are available. - * @param string $url The path to the RPC server on the called host. - * @param string $method The method to call. - * @param array $params A hash containing any necessary parameters for - * the method call. - * @param $options Associative array of parameters depending on - * the selected protocol driver. - * - * @return mixed The returned result from the method or a PEAR - * error object on failure. - */ - function request($driver, $url, $method, $params = null, $options = array()) - { - if (is_array($driver)) { - list($app, $driver) = $driver; - } - - $driver = basename($driver); - - if (!empty($app)) { - require_once $app . '/lib/RPC/' . $driver . '.php'; - } elseif (@file_exists(dirname(__FILE__) . '/RPC/' . $driver . '.php')) { - require_once dirname(__FILE__) . '/RPC/' . $driver . '.php'; - } else { - @include_once 'Horde/RPC/' . $driver . '.php'; - } - $class = 'Horde_RPC_' . $driver; - if (class_exists($class)) { - return call_user_func(array($class, 'request'), $url, $method, $params, $options); - } else { - require_once 'PEAR.php'; - return PEAR::raiseError('Class definition of ' . $class . ' not found.'); - } - } - - /** - * Attempts to return a concrete RPC server instance based on - * $driver. - * - * @param mixed $driver The type of concrete RPC subclass to return. If - * $driver is an array, then we will look in - * $driver[0]/lib/RPC/ for the subclass - * implementation named $driver[1].php. - * @param array $params A hash containing any additional configuration or - * connection parameters a subclass might need. - * - * @return Horde_RPC The newly created concrete Horde_RPC server instance, - * or a PEAR_Error on an error. - */ - function &factory($driver, $params = null) - { - if (is_array($driver)) { - list($app, $driver) = $driver; - } - - $driver = basename($driver); - - if (!empty($app)) { - require_once $app . '/lib/RPC/' . $driver . '.php'; - } elseif (@file_exists(dirname(__FILE__) . '/RPC/' . $driver . '.php')) { - require_once dirname(__FILE__) . '/RPC/' . $driver . '.php'; - } else { - @include_once 'Horde/RPC/' . $driver . '.php'; - } - $class = 'Horde_RPC_' . $driver; - if (class_exists($class)) { - $rpc = new $class($params); - } else { - require_once 'PEAR.php'; - $rpc = PEAR::raiseError('Class definition of ' . $class . ' not found.'); - } - - return $rpc; - } - - /** - * Attempts to return a reference to a concrete RPC server - * instance based on $driver. It will only create a new instance - * if no RPC server instance with the same parameters currently - * exists. - * - * This should be used if multiple RPC servers (and thus, multiple RPC - * server instances) are required. - * - * This method must be invoked as: $var = &Horde_RPC::singleton() - * - * @param string $driver The type of concrete RPC subclass to return. - * @param array $params A hash containing any additional configuration or - * connection parameters a subclass might need. - * - * @return Horde_RPC The concrete Horde_RPC server reference, or a - * PEAR_Error on an error. - */ - function &singleton($driver, $params = null) - { - static $instances; - - if (!isset($instances)) { - $instances = array(); - } - - $signature = serialize(array($driver, $params)); - if (!array_key_exists($signature, $instances)) { - $instances[$signature] = &Horde_RPC::factory($driver, $params); - } - - return $instances[$signature]; - } - -} diff --git a/phpgwapi/inc/horde/Horde/RPC/syncml.php b/phpgwapi/inc/horde/Horde/RPC/syncml.php deleted file mode 100644 index 2920523bdc..0000000000 --- a/phpgwapi/inc/horde/Horde/RPC/syncml.php +++ /dev/null @@ -1,273 +0,0 @@ - - * Copyright 2003-2006 Anthony Mills - * - * 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 - * @author Anthony Mills - * @since Horde 3.0 - * @package Horde_RPC - */ -class Horde_RPC_syncml extends Horde_RPC { - - /** - * Output ContentHandler used to output XML events. - * - * @var object - */ - var $_output; - - /** - * @var integer - */ - var $_xmlStack = 0; - - /** - * Debug directory, if set will store copies of all packets. - * - * @var string - */ - var $_debugDir = '/tmp/sync'; - - /** - * Default character set. Only supports UTF-8(ASCII?). - * - * @var string - */ - var $_charset = 'UTF-8'; - - /** - * SyncML handles authentication internally, so bypass the RPC framework - * auth check by just returning true here. - */ - function authorize() - { - return true; - } - - /** - * Sends an RPC request to the server and returns the result. - * - * @param string $request The raw request string. - * - * @return string The XML encoded response from the server. - */ - function getResponse($request) - { - /* Catch any errors/warnings/notices that may get thrown while - * processing. Don't want to let anything go to the client that's not - * part of the valid response. */ - ob_start(); - - /* Very useful for debugging. Logs WBXML packets to - * $this->_debugDir. */ - if (!empty($this->_debugDir) && is_dir($this->_debugDir)) { - $packetNum = @intval(file_get_contents($this->_debugDir . '/syncml.packetnum')); - if (!isset($packetNum)) { - $packetNum = 0; - } - - $f = @fopen($this->_debugDir . '/syncml_client_' . $packetNum . '.xml', 'wb'); - if ($f) { - fwrite($f, $request); - fclose($f); - } - } - - require_once 'XML/WBXML/ContentHandler.php'; - $this->_output = new XML_WBXML_ContentHandler(); - - $this->_parse($request); - $response = '_charset . '"?>'; - $response .= $this->_output->getOutput(); - - /* Very useful for debugging. */ - if (!empty($this->_debugDir) && is_dir($this->_debugDir)) { - $f = @fopen($this->_debugDir . '/syncml_server_' . $packetNum . '.xml', 'wb'); - if ($f) { - fwrite($f, $response); - fclose($f); - } - - $fp = @fopen($this->_debugDir . '/syncml.packetnum', 'w'); - if ($fp) { - fwrite($fp, ++$packetNum); - fclose($fp); - } - } - - /* Clear the output buffer that we started above, and log anything - * that came up for later debugging. */ - $errorLogging = ob_get_clean(); - if (!empty($errorLogging)) { - Horde::logMessage('SyncML: caught output=' . - $errorLogging, __FILE__, __LINE__, PEAR_LOG_DEBUG); - } - - return $response; - } - - function _parse($xml) - { - /* try to extract charset from XML text */ - if(preg_match('/^\s*<\?xml[^>]*encoding\s*=\s*"([^"]*)"/i', - $xml, $m)) { - $this->_charset = $m[1]; - } - #NLS::setCharset($this->_charset); - #String::setDefaultCharset($this->_charset); - - /* Create the XML parser and set method references. */ - $this->_parser = xml_parser_create_ns($this->_charset); - xml_set_object($this->_parser, $this); - xml_parser_set_option($this->_parser, XML_OPTION_CASE_FOLDING, false); - xml_set_element_handler($this->_parser, '_startElement', '_endElement'); - xml_set_character_data_handler($this->_parser, '_characters'); - xml_set_processing_instruction_handler($this->_parser, ''); - xml_set_external_entity_ref_handler($this->_parser, ''); - - if (!xml_parse($this->_parser, $xml)) { - return $this->raiseError(sprintf('XML error: %s at line %d', - xml_error_string(xml_get_error_code($this->_parser)), - xml_get_current_line_number($this->_parser))); - } - - xml_parser_free($this->_parser); - } - - function _startElement($parser, $tag, $attributes) - { - list($uri, $name) = $this->_splitURI($tag); - - $this->startElement($uri, $name, $attributes); - } - - function _characters($parser, $chars) - { - $this->characters($chars); - } - - function _endElement($parser, $tag) - { - list($uri, $name) = $this->_splitURI($tag); - - $this->endElement($uri, $name); - } - - function _splitURI($tag) - { - $parts = explode(':', $tag); - $name = array_pop($parts); - $uri = implode(':', $parts); - return array($uri, $name); - } - - /** - * Returns the Content-Type of the response. - * - * @return string The MIME Content-Type of the RPC response. - */ - function getResponseContentType() - { - return 'application/vnd.syncml+xml'; - } - - function startElement($uri, $element, $attrs) - { - $this->_xmlStack++; - - switch ($this->_xmlStack) { - case 1: - // - // Defined in SyncML Representation Protocol, version 1.1 5.2.1 - $this->_output->startElement($uri, $element, $attrs); - break; - - case 2: - // Either or - if (!isset($this->_contentHandler)) { - // If not defined then create SyncHdr. - $this->_contentHandler = new Horde_SyncML_SyncmlHdr(); - $this->_contentHandler->setOutput($this->_output); - } - - $this->_contentHandler->startElement($uri, $element, $attrs); - break; - - default: - if (isset($this->_contentHandler)) { - $this->_contentHandler->startElement($uri, $element, $attrs); - } - break; - } - } - - function endElement($uri, $element) - { - switch ($this->_xmlStack) { - case 1: - // - // Defined in SyncML Representation Protocol, version 1.1 5.2.1 - $this->_output->endElement($uri, $element); - break; - - case 2: - // Either or - if ($element == 'SyncHdr') { - // Then we get the state from SyncMLHdr, and create a new - // SyncMLBody. - $this->_contentHandler->endElement($uri, $element); - - unset($this->_contentHandler); - - $this->_contentHandler = new Horde_SyncML_SyncmlBody(); - $this->_contentHandler->setOutput($this->_output); - } else { - // No longer used. - $this->_contentHandler->endElement($uri, $element); - unset($this->_contentHandler); - } - break; - - default: - // or - if (isset($this->_contentHandler)) { - $this->_contentHandler->endElement($uri, $element); - } - break; - } - - if (isset($this->_chars)) { - unset($this->_chars); - } - - $this->_xmlStack--; - } - - function characters($str) - { - if (isset($this->_contentHandler)) { - $this->_contentHandler->characters($str); - } - } - - function raiseError($str) - { - return Horde::logMessage($str, __FILE__, __LINE__, PEAR_LOG_ERR); - } - -} diff --git a/phpgwapi/inc/horde/Horde/RPC/syncml_wbxml.php b/phpgwapi/inc/horde/Horde/RPC/syncml_wbxml.php deleted file mode 100644 index 3d478996a3..0000000000 --- a/phpgwapi/inc/horde/Horde/RPC/syncml_wbxml.php +++ /dev/null @@ -1,108 +0,0 @@ - - * Copyright 2003-2006 Anthony Mills - * - * 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 - * @author Anthony Mills - * @since Horde 3.0 - * @package Horde_RPC - */ -class Horde_RPC_syncml_wbxml extends Horde_RPC_syncml { - - /** - * Sends an RPC request to the server and returns the result. - * - * @param string $request The raw request string. - * - * @return string The WBXML encoded response from the server (binary). - */ - function getResponse($request) - { - /* Catch any errors/warnings/notices that may get thrown while - * processing. Don't want to let anything go to the client that's not - * part of the valid response. */ - ob_start(); - - /* Very useful for debugging. Logs WBXML packets to - * $this->_debugDir. */ - if (!empty($this->_debugDir) && is_dir($this->_debugDir)) { - $packetNum = @intval(file_get_contents($this->_debugDir . '/syncml.packetnum')); - if (!isset($packetNum)) { - $packetNum = 0; - } - - $fp = fopen($this->_debugDir . '/syncml_client_' . $packetNum . '.wbxml', 'wb'); - fwrite($fp, $request); - fclose($fp); - } - - - $decoder = new XML_WBXML_Decoder(); - $this->_output = new XML_WBXML_Encoder(); - - $decoder->setContentHandler($this); - - $r = $decoder->decode($request); - if (is_a($r, 'PEAR_Error')) { - Horde::logMessage('SyncML: ' . - $r->getMessage(), __FILE__, __LINE__, PEAR_LOG_ERR); - } - - $this->_output->setVersion($decoder->getVersion()); - $this->_output->setCharset($decoder->getCharsetStr()); - $response = $this->_output->getOutput(); - - if (is_a($response, 'PEAR_Error')) { - Horde::logMessage($response, __FILE__, __LINE__, PEAR_LOG_ERR); - $response = $response->getMessage(); - } - - if (!empty($this->_debugDir) && is_dir($this->_debugDir)) { - $fp = fopen($this->_debugDir . '/syncml_server_' . $packetNum . '.wbxml', 'wb'); - fwrite($fp, $response); - fclose($fp); - - $fp = @fopen($this->_debugDir . '/syncml.packetnum', 'w'); - if ($fp) { - fwrite($fp, ++$packetNum); - fclose($fp); - } - - } - - /* Clear the output buffer that we started above, and log anything - * that came up for later debugging. */ - $errorLogging = ob_get_clean(); - if (!empty($errorLogging)) { - Horde::logMessage('SyncML: caught output=' . $errorLogging, - __FILE__, __LINE__, PEAR_LOG_DEBUG); - } - - return $response; - } - - /** - * Returns the Content-Type of the response. - * - * @return string The MIME Content-Type of the RPC response. - */ - function getResponseContentType() - { - return 'application/vnd.syncml+wbxml'; - } - -} diff --git a/phpgwapi/inc/horde/Horde/Registry.php b/phpgwapi/inc/horde/Horde/Registry.php deleted file mode 100644 index 639b45a5f1..0000000000 --- a/phpgwapi/inc/horde/Horde/Registry.php +++ /dev/null @@ -1,1028 +0,0 @@ - - * Copyright 1999-2005 Jon Parise - * Copyright 1999-2005 Anil Madhavapeddy - * - * 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 - * @author Jon Parise - * @author Anil Madhavapeddy - * @since Horde 1.3 - * @package Horde_Framework - */ -class Registry { - - /** - * Hash storing all of the known services and callbacks. - * - * @var array $_apiCache - */ - var $_apiCache = array(); - - /** - * Hash storing all known data types. - * - * @var array $_typeCache - */ - var $_typeCache = array(); - - /** - * Hash storing all of the registered interfaces that applications - * provide. - * - * @var array $_interfaces - */ - var $_interfaces = array(); - - /** - * Hash storing information on each registry-aware application. - * - * @var array $applications - */ - var $applications = array(); - - /** - * Stack of in-use applications. - * - * @var array $_appStack - */ - var $_appStack = array(); - - /** - * Quick pointer to the current application. - * - * @var $_currentApp - */ - var $_currentApp = null; - - /** - * Cache of $prefs objects - * - * @var array $_prefsCache - */ - var $_prefsCache = array(); - - /** - * Cache of application configurations. - * - * @var array $_confCache - */ - var $_confCache = array(); - - /** - * Returns a reference to the global Registry object, only - * creating it if it doesn't already exist. - * - * This method must be invoked as: $registry = &Registry::singleton() - * - * @param optional integer $session_flags Any session flags. - * - * @return object Registry The Horde Registry instance. - */ - function &singleton($session_flags = 0) - { - static $registry; - - if (!isset($registry)) { - $registry = new Registry($session_flags); - } - - return $registry; - } - - /** - * Create a new registry instance. Should never be called except - * by &Registry::singleton(). - * - * @param optional integer $session_flags Any session flags. - * - * @access private - */ - function Registry($session_flags = 0) - { - /* Import and global Horde's configuration values. */ - $this->importConfig('horde'); - - /* Start a session. */ - if ($session_flags & HORDE_SESSION_NONE) { - /* Never start a session if the session flags include - HORDE_SESSION_NONE. */ - $_SESSION = array(); - } else { - Horde::setupSessionHandler(); - @session_start(); - if ($session_flags & HORDE_SESSION_READONLY) { - /* Close the session immediately so no changes can be - made but values are still available. */ - @session_write_close(); - } - } - - /* Read the registry configuration file. */ - require_once HORDE_BASE . '/config/registry.php'; - - /* Initialize the localization routines and variables. */ -# NLS::setLang(); -# NLS::setTextdomain('horde', HORDE_BASE . '/locale', NLS::getCharset()); -# String::setDefaultCharset(NLS::getCharset()); - - /* Stop system if Horde is inactive. */ - if ($this->applications['horde']['status'] == 'inactive') { - Horde::fatal(_("This system is currently deactivated."), __FILE__, __LINE__); - } - - /* Scan for all APIs provided by each app, and set other - * common defaults like templates and graphics. */ - $appList = array_keys($this->applications); - foreach ($appList as $appName) { - $app = &$this->applications[$appName]; - if (($app['status'] == 'heading') || - ($app['status'] == 'inactive') || - ($app['status'] == 'admin' && !Auth::isAdmin())) { - continue; - } - if (isset($app['provides'])) { - if (is_array($app['provides'])) { - foreach ($app['provides'] as $interface) { - $this->_interfaces[$interface] = $appName; - } - } else { - $this->_interfaces[$app['provides']] = $appName; - } - } - if (!isset($app['templates']) && isset($app['fileroot'])) { - $app['templates'] = $app['fileroot'] . '/templates'; - } - if (!isset($app['jsuri']) && isset($app['webroot'])) { - $app['jsuri'] = $app['webroot'] . '/js'; - } - if (!isset($app['jsfs']) && isset($app['fileroot'])) { - $app['jsfs'] = $app['fileroot'] . '/js'; - } - if (!isset($app['themesuri']) && isset($app['webroot'])) { - $app['themesuri'] = $app['webroot'] . '/themes'; - } - if (!isset($app['themesfs']) && isset($app['fileroot'])) { - $app['themesfs'] = $app['fileroot'] . '/themes'; - } - } - -# /* Create the global Perms object. */ -# $GLOBALS['perms'] = &Perms::singleton(); - -# /* Attach javascript notification listener. */ -# $notification = &Notification::singleton(); -# $notification->attach('javascript'); - - /* Register access key logger for translators. */ - if (@$GLOBALS['conf']['log_accesskeys']) { - register_shutdown_function(create_function('', 'Horde::getAccessKey(null, null, true);')); - } - } - - /** - * Return a list of the installed and registered applications. - * - * @since Horde 2.2 - * - * @access public - * - * @param array $filter (optional) An array of the statuses that - * should be returned. Defaults to non-hidden. - * @param boolean $assoc (optional) Associative array with app names - * as keys. - * @param integer $permission (optional) The permission level to check - * for in the list. Defaults to PERMS_SHOW. - * - * @return array List of apps registered with Horde. If no - * applications are defined returns an empty array. - */ - function listApps($filter = null, $assoc = false, $permission = PERMS_SHOW) - { - $apps = array(); - if (is_null($filter)) { - $filter = array('notoolbar', 'active'); - } - - foreach ($this->applications as $app => $params) { - if (in_array($params['status'], $filter) && - (defined('AUTH_HANDLER') || $this->hasPermission($app, $permission))) { - $assoc ? $apps[$app] = $app : $apps[] = $app; - } - } - - return $apps; - } - - /** - * Returns all available registry APIs. - * - * @access public - * - * @return array The API list. - */ - function listAPIs() - { - $apis = array(); - - foreach (array_keys($this->_interfaces) as $interface) { - @list($api, ) = explode('/', $interface); - $apis[] = $api; - } - - return array_unique($apis); - } - - /** - * Returns all of the available registry methods, or alternately - * only those for a specified API. - * - * @access public - * - * @param optional string $api Defines the API for which the methods - * shall be returned. - * - * @return array The method list. - */ - function listMethods($api = null) - { - $methods = array(); - - $this->_fillAPICache(); - - foreach (array_keys($this->applications) as $app) { - if (isset($this->applications[$app]['provides'])) { - $provides = $this->applications[$app]['provides']; - if (!is_array($provides)) { - $provides = array($provides); - } - } else { - $provides = array(); - } - - foreach ($provides as $method) { - if (strpos($method, '/') !== false) { - if (is_null($api) || - (substr($method, 0, strlen($api)) == $api)) { - $methods[] = $method; - } - } elseif (is_null($api) || ($method == $api)) { - if (isset($this->_apiCache[$app])) { - foreach (array_keys($this->_apiCache[$app]) as $service) { - $methods[] = $method . '/' . $service; - } - } - } - } - } - - return array_unique($methods); - } - - /** - * Returns all of the available registry data types. - * - * @access public - * - * @return array The data type list. - */ - function listTypes() - { - $this->_fillAPICache(); - return $this->_typeCache; - } - - /** - * Returns a method's signature. - * - * @access public - * - * @param string $method The full name of the method to check for. - * - * @return array A two dimensional array. The first element contains an - * array with the parameter names, the second one the return - * type. - */ - function getSignature($method) - { - if (!($app = $this->hasMethod($method))) { - return; - } - - $this->_fillAPICache(); - - @list(, $function) = explode('/', $method); - if (isset($this->_apiCache[$app][$function]['type']) && - isset($this->_apiCache[$app][$function]['args'])) { - return array($this->_apiCache[$app][$function]['args'], $this->_apiCache[$app][$function]['type']); - } - } - - /** - * Determine if an interface is implemented by an active - * application. - * - * @access public - * - * @param string $interface The interface to check for. - * - * @return mixed The application implementing $interface if we have it, - * false if the interface is not implemented. - */ - function hasInterface($interface) - { - return !empty($this->_interfaces[$interface]) ? - $this->_interfaces[$interface] : - false; - } - - /** - * Determine if a method has been registered with the registry. - * - * @access public - * - * @param string $method The full name of the method to check for. - * @param string $app (optional) Only check this application. - * - * @return mixed The application implementing $method if we have it, - * false if the method doesn't exist. - */ - function hasMethod($method, $app = null) - { - if (is_null($app)) { - @list($interface, $call) = explode('/', $method); - if (!empty($this->_interfaces[$method])) { - $app = $this->_interfaces[$method]; - } elseif (!empty($this->_interfaces[$interface])) { - $app = $this->_interfaces[$interface]; - } else { - return false; - } - } else { - $call = $method; - } - - $this->_fillAPICache(); - - return !empty($this->_apiCache[$app][$call]) ? $app : false; - } - - /** - * Return the hook corresponding to the default package that - * provides the functionality requested by the $method - * parameter. $method is a string consisting of - * "packagetype/methodname". - * - * @access public - * - * @param string $method The method to call. - * @param optional array $args Arguments to the method. - * - * @return TODO - * Returns PEAR_Error on error. - */ - function call($method, $args = array()) - { - @list($interface, $call) = explode('/', $method); - - if (!empty($this->_interfaces[$method])) { - $app = $this->_interfaces[$method]; - } elseif (!empty($this->_interfaces[$interface])) { - $app = $this->_interfaces[$interface]; - } else { - return PEAR::raiseError('The method "' . $method . '" is not defined in the Horde Registry.'); - } - - return $this->callByPackage($app, $call, $args); - } - - /** - * Output the hook corresponding to the specific package named. - * - * @access public - * - * @param string $app The application being called. - * @param string $call The method to call. - * @param optional array $args Arguments to the method. - * - * @return TODO - * Returns PEAR_Error on error. - */ - function callByPackage($app, $call, $args = array()) - { - /* Note: calling hasMethod() makes sure that we've cached - * $app's services and included the API file, so we don't try - * to do it again explicitly in this method. */ - if (!$this->hasMethod($call, $app)) { - return PEAR::raiseError(sprintf('The method "%s" is not defined in the API for %s.', $call, $app)); - } - - /* Make sure that the function actually exists. */ - $function = '_' . $app . '_' . $call; - if (!function_exists($function)) { - return PEAR::raiseError('The function implementing ' . $call . ' (' . $function . ') is not defined in ' . $app . '\'s API.'); - } - - $checkPerms = isset($this->_apiCache[$app][$call]['checkperms']) ? - $this->_apiCache[$app][$call]['checkperms'] : true; - - /* Switch application contexts now, if necessary, before - * including any files which might do it for us. Return an - * error immediately if pushApp() fails. */ - $pushed = $this->pushApp($app, $checkPerms); - if (is_a($pushed, 'PEAR_Error')) { - return $pushed; - } - - $res = call_user_func_array($function, $args); - - /* If we changed application context in the course of this - * call, undo that change now. */ - if ($pushed === true) { - $this->popApp(); - } - - return $res; - } - - /** - * Return the hook corresponding to the default package that - * provides the functionality requested by the $method - * parameter. $method is a string consisting of - * "packagetype/methodname". - * - * @access public - * - * @param string $method The method to link to. - * @param optional array $args Arguments to the method. - * @param optional mixed $extra Extra, non-standard arguments to the - * method. - * - * @return TODO - * Returns PEAR_Error on error. - */ - function link($method, $args = array(), $extra = '') - { - @list($interface, $call) = explode('/', $method); - - if (!empty($this->_interfaces[$method])) { - $app = $this->_interfaces[$method]; - } elseif (!empty($this->_interfaces[$interface])) { - $app = $this->_interfaces[$interface]; - } else { - return PEAR::raiseError('The method "' . $method . '" is not defined in the Horde Registry.'); - } - - return $this->linkByPackage($app, $call, $args, $extra); - } - - /** - * Output the hook corresponding to the specific package named. - * - * @access public - * - * @param string $app The application being called. - * @param string $call The method to link to. - * @param optional array $args Arguments to the method. - * @param optional mixed $extra Extra, non-standard arguments to the - * method. - * - * @return TODO - * Returns PEAR_Error on error. - */ - function linkByPackage($app, $call, $args = array(), $extra = '') - { - /* Note: calling hasMethod makes sure that we've cached $app's - * services and included the API file, so we don't try to do - * it it again explicitly in this method. */ - if (!$this->hasMethod($call, $app)) { - return PEAR::raiseError('The method "' . $call . '" is not defined in ' . $app . '\'s API.'); - } - - /* Make sure the link is defined. */ - if (empty($this->_apiCache[$app][$call]['link'])) { - return PEAR::raiseError('The link ' . $call . ' is not defined in ' . $app . '\'s API.'); - } - - /* Initial link value. */ - $link = $this->_apiCache[$app][$call]['link']; - - /* Fill in html-encoded arguments. */ - foreach ($args as $key => $val) { - $link = str_replace('%' . $key . '%', htmlentities($val), $link); - } - if (isset($this->applications[$app]['webroot'])) { - $link = str_replace('%application%', $this->get('webroot', $app), $link); - } - - /* Replace htmlencoded arguments that haven't been specified with - an empty string (this is where the default would be substituted - in a stricter registry implementation). */ - $link = preg_replace('|%.+%|U', '', $link); - - /* Fill in urlencoded arguments. */ - foreach ($args as $key => $val) { - $link = str_replace('|' . String::lower($key) . '|', urlencode($val), $link); - } - - /* Append any extra, non-standard arguments. */ - if (is_array($extra)) { - $extra_args = ''; - foreach ($extra as $key => $val) { - $extra_args .- '&' . urlencode($key) . '=' . urlencode($val); - } - } else { - $extra_args = $extra; - } - $link = str_replace('|extra|', $extra_args, $link); - - /* Replace html-encoded arguments that haven't been specified with - an empty string (this is where the default would be substituted - in a stricter registry implementation). */ - $link = preg_replace('|\|.+\||U', '', $link); - - return $link; - } - - /** - * Replace any %application% strings with the filesystem path to - * the application. - * - * @access public - * - * @param string $path The application string. - * @param optional string $app The application being called. - * - * @return TODO - * Returns PEAR_Error on error. - */ - function applicationFilePath($path, $app = null) - { - if (is_null($app)) { - $app = $this->_currentApp; - } - - if (!isset($this->applications[$app])) { - return PEAR::raiseError(sprintf(_("'%s' is not configured in the Horde Registry."), $app)); - } - - return str_replace('%application%', $this->applications[$app]['fileroot'], $path); - } - - /** - * Replace any %application% strings with the web path to the - * application. - * - * @access public - * - * @param string $path The application string. - * @param optional string $app The application being called. - * - * @return TODO - * Returns PEAR_Error on error. - */ - function applicationWebPath($path, $app = null) - { - if (!isset($app)) { - $app = $this->_currentApp; - } - - return str_replace('%application%', $this->applications[$app]['webroot'], $path); - } - - /** - * Set the current application, adding it to the top of the Horde - * application stack. If this is the first application to be - * pushed, retrieve session information as well. - * - * pushApp() also reads the application's configuration file and - * sets up its global $conf hash. - * - * @access public - * - * @param string $app The name of the application to push. - * @param boolean $checkPerms (optional) Make sure that the current user - * has permissions to the application being - * loaded. Defaults to true. Should ONLY - * be disabled by system scripts (cron jobs, - * etc.) and scripts that handle login. - * - * @return boolean Whether or not the _appStack was modified. - * Return PEAR_Error on error. - */ - function pushApp($app, $checkPerms = true) - { - if ($app == $this->_currentApp) { - return false; - } - - /* Bail out if application is not present or inactive. */ - if (!isset($this->applications[$app]) || - $this->applications[$app]['status'] == 'inactive' || - ($this->applications[$app]['status'] == 'admin' && !Auth::isAdmin())) { - Horde::fatal($app . ' is not activated', __FILE__, __LINE__); - } - - /* If permissions checking is requested, return an error if - * the current user does not have read perms to the - * application being loaded. We allow access: - * - * - To all admins. - * - To all authenticated users if no permission is set on $app. - * - To anyone who is allowed by an explicit ACL on $app. */ - if ($checkPerms && !$this->hasPermission($app)) { - Horde::logMessage(sprintf('User %s does not have READ permission for %s', Auth::getAuth(), $app), __FILE__, __LINE__, PEAR_LOG_DEBUG); - return PEAR::raiseError(sprintf(_("User %s is not authorised for %s."), Auth::getAuth(), $this->applications[$app]['name']), 'permission_denied'); - } - - /* Import this application's configuration values. */ - $success = $this->importConfig($app); - if (is_a($success, 'PEAR_Error')) { - return $success; - } - - /* Load preferences after the configuration has been loaded to - * make sure the prefs file has all the information it needs. */ - $this->loadPrefs($app); - - /* Reset the language in case there is a different one - * selected in the preferences. */ - $language = ''; - if (isset($this->_prefsCache[$app]) && - isset($this->_prefsCache[$app]->_prefs['language'])) { - $language = $this->_prefsCache[$app]->getValue('language'); - } - NLS::setLang($language); - NLS::setTextdomain($app, $this->applications[$app]['fileroot'] . '/locale', NLS::getCharset()); - String::setDefaultCharset(NLS::getCharset()); - - /* Once we know everything succeeded and is in a consistent - * state again, push the new application onto the stack. */ - array_push($this->_appStack, $app); - $this->_currentApp = $app; - - return true; - } - - /** - * Remove the current app from the application stack, setting the - * current app to whichever app was current before this one took - * over. - * - * @access public - * - * @return string The name of the application that was popped. - */ - function popApp() - { - /* Pop the current application off of the stack. */ - $previous = array_pop($this->_appStack); - - /* Import the new active application's configuration values - * and set the gettext domain and the preferred language. */ - $this->_currentApp = count($this->_appStack) ? end($this->_appStack) : null; - if ($this->_currentApp) { - $this->importConfig($this->_currentApp); - $this->loadPrefs($this->_currentApp); - #$language = $GLOBALS['prefs']->getValue('language'); - #if (isset($language)) { - # NLS::setLang($language); - #} - NLS::setTextdomain($this->_currentApp, $this->applications[$this->_currentApp]['fileroot'] . '/locale', NLS::getCharset()); - String::setDefaultCharset(NLS::getCharset()); - } - - return $previous; - } - - /** - * Return the current application - the app at the top of the - * application stack. - * - * @access public - * - * @return string The current application. - */ - function getApp() - { - return $this->_currentApp; - } - - /** - * Check permissions on an application. - * - * @access public - * - * @return boolean Whether or not access is allowed. - */ - function hasPermission($app, $permission = PERMS_READ) - { - return true; - #return Auth::isAdmin() || ($GLOBALS['perms']->exists($app) ? - # $GLOBALS['perms']->hasPermission($app, Auth::getAuth(), $permission) : - # (bool)Auth::getAuth()); - } - - /** - * Reads the configuration values for the given application and - * imports them into the global $conf variable. - * - * @access public - * - * @param string $app The name of the application. - * - * @return boolean True on success, PEAR_Error on error. - */ - function importConfig($app) - { - /* Don't make config files global $registry themselves. */ - global $registry; - - /* Cache config values so that we don't re-read files on every - * popApp() call. */ - if (!isset($this->_confCache[$app])) { - if (!isset($this->_confCache['horde'])) { - $conf = array(); - ob_start(); - $success = include HORDE_BASE . '/config/conf.php'; - $errors = ob_get_contents(); - ob_end_clean(); - if (!empty($errors)) { - return PEAR::raiseError(sprintf('Failed to import Horde configuration: %s', strip_tags($errors))); - } - if (!$success) { - return PEAR::raiseError('Failed to import Horde configuration.'); - } - - /* Initial Horde-wide settings. */ - - /* Set the error reporting level in accordance with - * the config settings. */ - error_reporting($conf['debug_level']); - - /* Set the maximum execution time in accordance with - * the config settings. */ - @set_time_limit($conf['max_exec_time']); - - /* Set the umask according to config settings. */ - if (isset($conf['umask'])) { - umask($conf['umask']); - } - } else { - $conf = $this->_confCache['horde']; - } - - if ($app !== 'horde') { - $success = @include $this->applications[$app]['fileroot'] . '/config/conf.php'; - if (!$success) { - return PEAR::raiseError('Failed to import application configuration for ' . $app); - } - } - - $this->_confCache[$app] = &$conf; - } - - $GLOBALS['conf'] = &$this->_confCache[$app]; - return true; - } - - /** - * Loads the preferences for the current user for the current - * application and imports them into the global $prefs variable. - * - * @access public - * - * @param string $app The name of the application. - */ - function loadPrefs($app = null) - { - return array(); - - static $prefs_default = false; - - require_once 'Horde/Prefs.php'; - - if ($app === null) { - $app = $this->_currentApp; - } - - /* If there is no logged in user, return an empty Prefs:: - * object with just default preferences. */ -# if (!Auth::getAuth()) { -# $prefs = &Prefs::factory('none', $app, '', '', null, false); -# $prefs->retrieve(); -# $this->_prefsCache[$app] = &$prefs; -# $GLOBALS['prefs'] = &$this->_prefsCache[$app]; -# $prefs_default = true; -# return; -# } - - /* Cache prefs objects so that we don't re-load them on every - * popApp() call. */ -# if (!isset($this->_prefsCache[$app]) || -# !empty($prefs_default)) { -# $prefs = &Prefs::factory($GLOBALS['conf']['prefs']['driver'], $app, -# Auth::getAuth(), Auth::getCredential('password')); -# $prefs->retrieve(); -# $this->_prefsCache[$app] = &$prefs; -# } - - $GLOBALS['prefs'] = &$this->_prefsCache[$app]; - } - - /** - * Unload preferences from an application or (if no application is - * specified) from ALL applications. Useful when a user has logged - * out but you need to continue on the same page, etc. - * - * After unloading, if there is an application on the app stack to - * load preferences from, then we reload a fresh set. - * - * @access public - * - * @param string $app (optional) The application to unload prefrences for. - * If null, ALL preferences are reset. - */ - function unloadPrefs($app = null) - { - if ($app === null) { - $this->_prefsCache = array(); - } elseif (isset($this->_prefsCache[$app])) { - unset($this->_prefsCache[$app]); - } else { - return; - } - - if ($this->_currentApp) { - $this->loadPrefs(); - } - } - - /** - * Return the requested configuration parameter for the specified - * application. If no application is specified, the value of - * $this->_currentApp (the current application) is used. However, - * if the parameter is not present for that application, the - * Horde-wide value is used instead. If that is not present, we - * return null. - * - * @access public - * - * @param string $parameter The configuration value to retrieve. - * @param optional string $app The application to get the value for. - * - * @return string The requested parameter, or null if it is not set. - */ - function get($parameter, $app = null) - { - if (is_null($app)) { - $app = $this->_currentApp; - } - - if (isset($this->applications[$app][$parameter])) { - $pval = $this->applications[$app][$parameter]; - } else { - if ($parameter == 'icon') { - $pval = $this->_getIcon($app); - } else { - $pval = isset($this->applications['horde'][$parameter]) ? $this->applications['horde'][$parameter] : null; - } - } - - if ($parameter == 'name') { - return _($pval); - } else { - return $pval; - } - } - - /** - * Function to work out an application's graphics URI, taking into - * account any themes directories that may be set up. - * - * @access public - * - * @param optional string $app The application for which to get the - * image directory. If blank will default - * to current application. - * - * @return string The image directory uri path. - */ - function getImageDir($app = null) - { - if (empty($app)) { - $app = $this->_currentApp; - } - - static $img_dir = array(); - if (isset($img_dir[$app])) { - return $img_dir[$app]; - } - - /* This is the default location for the graphics. */ - $img_dir[$app] = $this->get('themesuri', $app) . '/graphics'; - - /* Figure out if this is going to be overridden by any theme - * settings. */ - if (isset($GLOBALS['prefs']) && ($theme = $GLOBALS['prefs']->getValue('theme')) && - (@include $this->get('themesfs', 'horde') . '/' . $theme . '/info.php') && - isset($theme_icons) && - in_array($app, $theme_icons)) { - $img_dir[$app] = $this->get('themesuri', $app) . '/' . $theme . '/graphics'; - } - - return $img_dir[$app]; - } - - /** - * Returns the path to an application's icon, respecting whether the - * current theme has its own icons. - * - * @access private - * - * @param string $app The application for which to get the icon. - */ - function _getIcon($app) - { - return $this->getImageDir($app) . '/' . $app . '.png'; - } - - /** - * Query the initial page for an application - the webroot, if - * there is no initial_page set, and the initial_page, if it is - * set. - * - * @access public - * - * @param optional string $app The name of the application. - * - * @return string URL pointing to the inital page of the application. - * Returns PEAR_Error on error. - */ - function getInitialPage($app = null) - { - if (is_null($app)) { - $app = $this->_currentApp; - } - - if (!isset($this->applications[$app])) { - return PEAR::raiseError(sprintf(_("'%s' is not configured in the Horde Registry."), $app)); - } - return $this->applications[$app]['webroot'] . '/' . (isset($this->applications[$app]['initial_page']) ? $this->applications[$app]['initial_page'] : ''); - } - - /** - * Fills the registry's API cache with the available services. - * - * @access private - */ - function _fillAPICache() - { - if (!empty($this->_apiCache)) { - return; - } - - $status = array('active', 'notoolbar', 'hidden'); -# if (Auth::isAdmin()) { -# $status[] = 'admin'; -# } - $apps = $this->listApps($status); - foreach ($apps as $app) { - $_services = $_types = null; - $api = $this->get('fileroot', $app) . '/lib/api.php'; - if (is_readable($api)) { - include_once $api; - } - if (!isset($_services)) { - $this->_apiCache[$app] = array(); - } else { - $this->_apiCache[$app] = $_services; - } - if (isset($_types)) { - foreach ($_types as $type => $params) { - /* Prefix non-Horde types with the application - * name. */ - $prefix = $app == 'horde' ? '' : "${app}_"; - $this->_typeCache[$prefix . $type] = $params; - } - } - } - } - -} diff --git a/phpgwapi/inc/horde/Horde/String.php b/phpgwapi/inc/horde/Horde/String.php deleted file mode 100644 index 608ac222f3..0000000000 --- a/phpgwapi/inc/horde/Horde/String.php +++ /dev/null @@ -1,705 +0,0 @@ - - * @since Horde 3.0 - * @package Horde_Util - */ -class String { - - /** - * Caches the result of extension_loaded() calls. - * - * @param string $ext The extension name. - * - * @return boolean Is the extension loaded? - * - * @see Util::extensionExists() - */ - public static function extensionExists($ext) - { - static $cache = array(); - - if (!isset($cache[$ext])) { - $cache[$ext] = extension_loaded($ext); - } - - return $cache[$ext]; - } - - /** - * Sets a default charset that the String:: methods will use if none is - * explicitly specified. - * - * @param string $charset The charset to use as the default one. - */ - public static function setDefaultCharset($charset) - { - $GLOBALS['_HORDE_STRING_CHARSET'] = $charset; - if (String::extensionExists('mbstring') && - function_exists('mb_regex_encoding')) { - $old_error = error_reporting(0); - mb_regex_encoding(String::_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 - * $_HORDE_STRING_CHARSET will be used. - * - * @return mixed The converted input data. - */ - public static 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 = $GLOBALS['_HORDE_STRING_CHARSET']; - } - - /* If the from and to character sets are identical, return now. */ - if ($from == $to) { - return $input; - } - $from = String::lower($from); - $to = String::lower($to); - if ($from == $to) { - return $input; - } - - if (is_array($input)) { - $tmp = array(); - reset($input); - while (list($key, $val) = each($input)) { - $tmp[String::_convertCharset($key, $from, $to)] = String::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 = String::convertCharset($val, $from, $to); - } - return $input; - } - - if (!is_string($input)) { - return $input; - } - - return String::_convertCharset($input, $from, $to); - } - - /** - * Internal public static function used to do charset conversion. - * - * @access private - * - * @param string $input See String::convertCharset(). - * @param string $from See String::convertCharset(). - * @param string $to See String::convertCharset(). - * - * @return string The converted string. - */ - public static function _convertCharset($input, $from, $to) - { - $output = ''; - $from_check = (($from == 'iso-8859-1') || ($from == 'us-ascii')); - $to_check = (($to == 'iso-8859-1') || ($to == 'us-ascii')); - - /* 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 - * public static functions use more memory. */ - if (strlen($input) < 16777216 || !(String::extensionExists('iconv') || String::extensionExists('mbstring'))) { - if ($from_check && ($to == 'utf-8')) { - return utf8_encode($input); - } - - if (($from == 'utf-8') && $to_check) { - return utf8_decode($input); - } - } - - /* First try iconv with transliteration. */ - if (($from != 'utf7-imap') && - ($to != 'utf7-imap') && - String::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); - $output = @iconv($from, $to . '//TRANSLIT', $input . 'x'); - $output = (isset($php_errormsg)) ? false : String::substr($output, 0, -1, $to); - ini_set('track_errors', $oldTrackErrors); - } - - /* Next try mbstring. */ - if (!$output && String::extensionExists('mbstring')) { - $old_error = error_reporting(0); - $output = mb_convert_encoding($input, $to, String::_mbstringCharset($from)); - error_reporting($old_error); - } - - /* At last try imap_utf7_[en|de]code if appropriate. */ - if (!$output && String::extensionExists('imap')) { - if ($from_check && ($to == 'utf7-imap')) { - return @imap_utf7_encode($input); - } - if (($from == 'utf7-imap') && $to_check) { - return @imap_utf7_decode($input); - } - } - - return (!$output) ? $input : $output; - } - - /** - * 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 - */ - public static function lower($string, $locale = false, $charset = null) - { - static $lowers; - - if ($locale) { - /* The existence of mb_strtolower() depends on the platform. */ - if (String::extensionExists('mbstring') && - function_exists('mb_strtolower')) { - if (is_null($charset)) { - $charset = $GLOBALS['_HORDE_STRING_CHARSET']; - } - $old_error = error_reporting(0); - $ret = mb_strtolower($string, String::_mbstringCharset($charset)); - error_reporting($old_error); - if (!empty($ret)) { - return $ret; - } - } - return strtolower($string); - } - - if (!isset($lowers)) { - $lowers = array(); - } - if (!isset($lowers[$string])) { - $language = setlocale(LC_CTYPE, 0); - setlocale(LC_CTYPE, 'C'); - $lowers[$string] = strtolower($string); - setlocale(LC_CTYPE, $language); - } - - return $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 - */ - public static function upper($string, $locale = false, $charset = null) - { - static $uppers; - - if ($locale) { - /* The existence of mb_strtoupper() depends on the - * platform. */ - if (function_exists('mb_strtoupper')) { - if (is_null($charset)) { - $charset = $GLOBALS['_HORDE_STRING_CHARSET']; - } - $old_error = error_reporting(0); - $ret = mb_strtoupper($string, String::_mbstringCharset($charset)); - error_reporting($old_error); - if (!empty($ret)) { - return $ret; - } - } - return strtoupper($string); - } - - if (!isset($uppers)) { - $uppers = array(); - } - if (!isset($uppers[$string])) { - $language = setlocale(LC_CTYPE, 0); - setlocale(LC_CTYPE, 'C'); - $uppers[$string] = strtoupper($string); - setlocale(LC_CTYPE, $language); - } - - return $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. - */ - public static function ucfirst($string, $locale = false, $charset = null) - { - if ($locale) { - $first = String::substr($string, 0, 1, $charset); - if (String::isAlpha($first, $charset)) { - $string = String::upper($first, true, $charset) . String::substr($string, 1, null, $charset); - } - } else { - $string = String::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. - */ - public static function substr($string, $start, $length = null, $charset = null) - { - if (is_null($length)) { - $length = String::length($string, $charset) - $start; - } - - if ($length == 0) { - return ''; - } - - /* Try mbstring. */ - if (String::extensionExists('mbstring')) { - if (is_null($charset)) { - $charset = $GLOBALS['_HORDE_STRING_CHARSET']; - } - $old_error = error_reporting(0); - $ret = mb_substr($string, $start, $length, String::_mbstringCharset($charset)); - error_reporting($old_error); - /* mb_substr() returns empty string on failure. */ - if (strlen($ret)) { - return $ret; - } - } - - /* Try iconv. */ - if (function_exists('iconv_substr')) { - if (is_null($charset)) { - $charset = $GLOBALS['_HORDE_STRING_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; - } - } - - 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 string The string's part. - */ - public static function length($string, $charset = null) - { - if (is_null($charset)) { - $charset = $GLOBALS['_HORDE_STRING_CHARSET']; - } - $charset = String::lower($charset); - if (String::extensionExists('mbstring')) { - $old_error = error_reporting(0); - $ret = mb_strlen($string, String::_mbstringCharset($charset)); - error_reporting($old_error); - if (!empty($ret)) { - return $ret; - } - } - if ($charset == 'utf-8' || $charset == 'utf8') { - return strlen(utf8_decode($string)); - } - 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. - */ - public static function pos($haystack, $needle, $offset = 0, $charset = null) - { - if (String::extensionExists('mbstring')) { - if (is_null($charset)) { - $charset = $GLOBALS['_HORDE_STRING_CHARSET']; - } - $track_errors = ini_set('track_errors', 1); - $old_error = error_reporting(0); - $ret = mb_strpos($haystack, $needle, $offset, String::_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. - */ - public static function pad($input, $length, $pad = ' ', $type = STR_PAD_RIGHT, - $charset = null) - { - $mb_length = String::length($input, $charset); - $sb_length = strlen($input); - $pad_length = String::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 = String::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 = String::substr(str_repeat($pad, ceil($left / $pad_length)), 0, $left, $charset) . - $input . - String::substr(str_repeat($pad, ceil($right / $pad_length)), 0, $right, $charset); - break; - case STR_PAD_RIGHT: - $right = $length - $mb_length; - $output = $input . String::substr(str_repeat($pad, ceil($right / $pad_length)), 0, $right, $charset); - break; - } - - return $output; - } - - /** - * Wraps the text of a message. - * - * @since Horde 3.2 - * - * @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. - */ - public static 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 = $GLOBALS['_HORDE_STRING_CHARSET']; - } - $charset = String::_mbstringCharset($charset); - $string = String::convertCharset($string, $charset, 'utf-8'); - $wrapped = ''; - - while (String::length($string, 'utf-8') > $width) { - $line = String::substr($string, 0, $width, 'utf-8'); - $string = String::substr($string, String::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).*)/us', $string, $match)) { - $line .= $match[1]; - $string = $match[2]; - } - // 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. - if ($line_folding) { - $sub = '(.+[^\s])'; - } else { - $sub = '(.*)'; - } - 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 .= $line . $break; - continue; - } - $wrapped .= $line; - } - - return String::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. - */ - public static 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 = String::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 The string to test. - * @param $charset The charset to use when testing the string. - * - * @return boolean True if the parameter was alphabetic only. - */ - public static function isAlpha($string, $charset = null) - { - if (!String::extensionExists('mbstring')) { - return ctype_alpha($string); - } - - $charset = String::_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 The string to test. - * @param $charset The charset to use when testing the string. - * - * @return boolean True if the parameter was lowercase. - */ - public static function isLower($string, $charset = null) - { - return ((String::lower($string, true, $charset) === $string) && - String::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. - */ - public static function isUpper($string, $charset = null) - { - return ((String::upper($string, true, $charset) === $string) && - String::isAlpha($string, $charset)); - } - - /** - * Performs a multibyte safe regex match search on the text provided. - * - * @since Horde 3.1 - * - * @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. - */ - public static function regexMatch($text, $regex, $charset = null) - { - if (!empty($charset)) { - $regex = String::convertCharset($regex, $charset, 'utf-8'); - $text = String::convertCharset($text, $charset, 'utf-8'); - } - - $matches = array(); - foreach ($regex as $val) { - if (preg_match('/' . $val . '/u', $text, $matches)) { - break; - } - } - - if (!empty($charset)) { - $matches = String::convertCharset($matches, 'utf-8', $charset); - } - - return $matches; - } - - /** - * Workaround charsets that don't work with mbstring public static functions. - * - * @access private - * - * @param string $charset The original charset. - * - * @return string The charset to use with mbstring public static functions. - */ - public static function _mbstringCharset($charset) - { - /* mbstring public static 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(String::lower($charset), array('ks_c_5601-1987', 'ks_c_5601-1989'))) { - $charset = 'UHC'; - } - - return $charset; - } - -} diff --git a/phpgwapi/inc/horde/Horde/SyncML.php b/phpgwapi/inc/horde/Horde/SyncML.php deleted file mode 100644 index 6eed33fafc..0000000000 --- a/phpgwapi/inc/horde/Horde/SyncML.php +++ /dev/null @@ -1,752 +0,0 @@ - - * @author Karsten Fourmont - * @author Joerg Lehrke - * @copyright (c) The Horde Project (http://www.horde.org/) - * @version $Id$ - */ - -include_once 'Horde/SyncML/Command.php'; -include_once 'Horde/SyncML/Command/Status.php'; -include_once 'Horde/SyncML/Command/Alert.php'; -include_once 'Horde/SyncML/Command/Final.php'; -include_once 'Horde/SyncML/Command/Sync.php'; -include_once 'Horde/SyncML/Sync.php'; -include_once 'Horde/SyncML/Command/Sync/SyncElementItem.php'; - -class Horde_SyncML_ContentHandler { - - /** - * Output ContentHandler used to output XML events. - * @var object $_output - */ - var $_output; - - /** - * @var integer $_xmlStack - */ - var $_xmlStack = 1; - - /** - * @var string $_chars - */ - var $_chars; - - function setOutput(&$output) - { - $this->_output = &$output; - } - - function startElement($uri, $element, $attrs) - { - $this->_xmlStack++; - } - - function endElement($uri, $element) - { - if (isset($this->_chars)) { - unset($this->_chars); - } - - $this->_xmlStack--; - } - - function characters($str) - { - if (isset($this->_chars)) { - $this->_chars = $this->_chars . $str; - } else { - $this->_chars = $str; - } - } - -} - -/** - * Defined in SyncML Representation Protocol, version 1.1 5.2.2 - * - * @package Horde_SyncML - */ -class Horde_SyncML_SyncMLHdr extends Horde_SyncML_ContentHandler { - - /** - * Used to specify if in Source tag. Defined in SyncML - * Representation Protocol, version 1.1 5.1.20. - * - * @var boolean $_isSource - */ - var $_isSource = false; - - /** - * Defined in SyncML Representation Protocol, version 1.1 - * 5.1.9. User name. - * - * @var string $_locName - */ - var $_locName; - - /** - * Defined in SyncML Representation Protocol, version 1.1 5.1.18 - * - * @var string $_sessionID - */ - - var $_sessionID; - - /** - * Defined in SyncML Representation Protocol, version 1.1. Must - * be 1.0 (0), 1.1 (1) or 1.2(2). - * - * @var string $_version - */ - var $_version; - - /** - * Defined in SyncML Representation Protocol, version 1.1 5.1.12 - * - * @var string $_msgID - */ - var $_msgID; - - /** - * Defined in SyncML Representation Protocol, version 1.1 5.1.10 - * - * @var string $_targetURI - */ - var $_targetURI; - - /** - * Defined in SyncML Representation Protocol, version 1.1 5.1.10, - * 5.1.20 - * - * @var string $_sourceURI - */ - var $_sourceURI; - - var $_isCred; - - var $_credData; - - var $_credFormat; - - var $_credType; - - var $_maxMsgSize; - - function &getStateFromSession($sourceURI, $locName, $sessionID) - { - // Remove any existing session since we'll be contructing a - // custom session id. - session_regenerate_id(); - session_destroy(); - - // we need to (re-)load the eGW session-handler, as session_destroy unloads custom session-handlers - if (function_exists('init_session_handler')) { - init_session_handler(); - } - - // Reload the Horde SessionHandler if necessary. - Horde::setupSessionHandler(); - - // It would seem multisync does not send the user name once it - // has been authorized. Make sure we have a valid session id. - if(!empty($_GET['syncml_sessionid'])) { - session_id($_GET['syncml_sessionid']); - Horde::logMessage('SyncML['. session_id() .']: reusing existing session', - __FILE__, __LINE__, PEAR_LOG_DEBUG); - } else { - #session_id('syncml' . preg_replace('/[^a-zA-Z0-9]/', '', $sourceURI . $sessionID)); - session_id('syncml-' . md5(uniqid(rand(), true))); - Horde::logMessage('SyncML['. session_id() .']: starting new session for ' - . $this->_locName, __FILE__, __LINE__, PEAR_LOG_INFO); - } - - @session_start(); - - if (!isset($_SESSION['SyncML.state'])) { - // Create a new state if one does not already exist. - Horde::logMessage('SyncML['. session_id() .']: create new session state variable for ' - . $sourceURI, __FILE__, __LINE__, PEAR_LOG_DEBUG); - - $_SESSION['SyncML.state'] = new EGW_SyncML_State($sourceURI, $locName, $sessionID); - } - - - if ($_SESSION['SyncML.state']->isAuthorized()) { - Horde::logMessage('SyncML['. session_id() .']: session is authorized', - __FILE__, __LINE__, PEAR_LOG_DEBUG); - } - #Horde::logMessage('SyncML['. session_id() . "]:\n" . print_r($_SESSION['SyncML.state'], true), __FILE__, __LINE__, PEAR_LOG_DEBUG); - - return $_SESSION['SyncML.state']; - } - - function startElement($uri, $element, $attrs) - { - parent::startElement($uri, $element, $attrs); - - switch ($this->_xmlStack) { - case 3: - if ($element == 'Source') { - // - $this->_isSource = true; - } elseif ($element == 'Cred') { - $this->_isCred = true; - } - break; - } - } - - function endElement($uri, $element) - { - switch ($this->_xmlStack) { - case 2: - // - Horde::logMessage('SyncML['. session_id() .']: package ' - . $this->_msgID.' +++++++++++++++++++++ started', - __FILE__, __LINE__, PEAR_LOG_DEBUG); - - // Find the state. - //Horde::logMessage('SymcML: SyncHdr done. Try to load state from session.', - // __FILE__, __LINE__, PEAR_LOG_DEBUG); - $state =& $this->getStateFromSession($this->_sourceURI, $this->_locName, $this->_sessionID); - - $state->setVersion($this->_version); - $state->setMsgID($this->_msgID); - $state->setTargetURI($this->_targetURI); - $state->setWBXML(is_a($this->_output, 'XML_WBXML_Encoder')); - - if (isset($this->_credData) - && isset($this->_locName) - && !$state->isAuthorized()) { - $state->setPassword($this->_credData); - $state->setLocName($this->_locName); - } - - if (isset($this->_maxMsgSize)) { - $state->setMaxMsgSize($this->_maxMsgSize); - } - - // $_SESSION['SyncML.state'] = $state; - - #Horde::logMessage('SymcML: session id 2 =' . session_id(), __FILE__, __LINE__, PEAR_LOG_DEBUG); - - // Got the state; now write our SyncHdr header. - $this->outputSyncHdr($this->_output); - break; - - case 3: - if ($element == 'VerProto') { - // - switch (strtolower(trim($this->_chars))) { - case 'syncml/1.2': - $this->_version = 2; - break; - case 'syncml/1.1': - $this->_version = 1; - break; - default: - $this->_version = 0; - break; - } - } elseif ($element == 'SessionID') { - // - $this->_sessionID = trim($this->_chars); - } elseif ($element == 'MsgID') { - // - $this->_msgID = intval(trim($this->_chars)); - } elseif ($element == 'Source') { - // - $this->_isSource = false; - } elseif ($element == 'Cred') { - // - $this->_isCred = false; - - // We only support b64 for now - //if ($this->_credFormat == 'b64') { - $this->_credData = base64_decode($this->_credData); - //} - - $tmp = explode(':', $this->_credData, 2); - // set only if not set by LocName already - if (!isset($this->_locName)) { - $this->_locName = $tmp[0]; - } - $this->_credData = $tmp[1]; - - #Horde::logMessage('SyncML['. session_id() .']: $this->_locName: ' . $this->_locName, __FILE__, __LINE__, PEAR_LOG_DEBUG); - } - break; - - case 4: - switch ($element) { - case 'LocURI': - if ($this->_isSource) { - // - $this->_sourceURI = trim($this->_chars); - } else { - // - $this->_targetURI = trim($this->_chars); - } - break; - case 'LocName': - if ($this->_isSource) { - // - $this->_locName = trim($this->_chars); - } - break; - case 'Data': - // - if ($this->_isCred) { - $this->_credData = trim($this->_chars); - } - break; - case 'MaxMsgSize': - // - $this->_maxMsgSize = trim($this->_chars); - break; - } - break; - - case 5: - if ($this->_isCred) { - if ($element == 'Format') { - // - $this->_credFormat = trim($this->_chars); - } elseif ($element == 'Type') { - // - $this->_credType = trim($this->_chars); - } - } - break; - } - - parent::endElement($uri, $element); - } - - function outputSyncHdr(&$output) - { - $attrs = array(); - - $state =& $_SESSION['SyncML.state']; - - $uri = $state->getURI(); - $uriMeta = $state->getURIMeta(); - $output->startElement($uri, 'SyncHdr', $attrs); - - $output->startElement($uri, 'VerDTD', $attrs); - if ($this->_version == 2) { - $chars = '1.2'; - } elseif ($this->_version == 1) { - $chars = '1.1'; - } else { - $chars = '1.0'; - } - $output->characters($chars); - $output->endElement($uri, 'VerDTD'); - - $output->startElement($uri, 'VerProto', $attrs); - if ($this->_version == 2) { - $chars = 'SyncML/1.2'; - } elseif ($this->_version == 1) { - $chars = 'SyncML/1.1'; - } else { - $chars = 'SyncML/1.0'; - } - $output->characters($chars); - $output->endElement($uri, 'VerProto'); - - $output->startElement($uri, 'SessionID', $attrs); - $output->characters($this->_sessionID); - $output->endElement($uri, 'SessionID'); - - $output->startElement($uri, 'MsgID', $attrs); - $output->characters($this->_msgID); - $output->endElement($uri, 'MsgID'); - - $output->startElement($uri, 'Target', $attrs); - $output->startElement($uri, 'LocURI', $attrs); - $output->characters($this->_sourceURI); - $output->endElement($uri, 'LocURI'); - $output->endElement($uri, 'Target'); - - $output->startElement($uri, 'Source', $attrs); - $output->startElement($uri, 'LocURI', $attrs); - $output->characters($this->_targetURI); - $output->endElement($uri, 'LocURI'); - $output->endElement($uri, 'Source'); - - if (session_id() != '' && !strpos($this->_targetURI,'syncml_sessionid')) { - $output->startElement($uri, 'RespURI', $attrs); - - // some clients don't send the whole URL as targetURI - if (strpos($this->_targetURI,$_SERVER['PHP_SELF']) === false) { - $output->characters($this->_targetURI . $_SERVER['PHP_SELF'] . '?syncml_sessionid=' . session_id()); - } else { - $output->characters($this->_targetURI . '?syncml_sessionid=' . session_id()); - } - $output->endElement($uri, 'RespURI'); - } - - - $output->startElement($uri, 'Meta', $attrs); - - if (!($maxMsgSize = $state->getMaxMsgSizeClient()) || $maxMsgSize > 10000) { - // Use a realistic message size to cope with - $maxMsgSize = 10000; - } - $output->startElement($uriMeta, 'MaxMsgSize', $attrs); - $output->characters($maxMsgSize); - $output->endElement($uriMeta, 'MaxMsgSize'); - - #// Dummy MaxObjSize, this is just put in to make the packet - #// work, it is not our real value. - #if ($this->_version > 0) { - # // Don't send this to old devices - # $output->startElement($uriMeta, 'MaxObjSize', $attrs); - # $output->characters('4000000'); - # $output->endElement($uriMeta, 'MaxObjSize'); - #} - - $output->endElement($uri, 'Meta'); - - $output->endElement($uri, 'SyncHdr'); - } - - function getSourceURI() - { - return $this->_sourceURI; - } - - function getLocName() - { - return $this->_locName; - } - - function getSessionID() - { - return $this->_sessionID; - } - - function getVersion() - { - return $this->_version; - } - - function getMsgID() - { - return $this->_msgID; - } - - function getTargetURI() - { - return $this->_targetURI; - } - - function opaque($o) - { - } - -} - -/** - * Defined in SyncML Representation Protocol, version 1.1 5.2.3 - * - * @package Horde_SyncML - */ -class Horde_SyncML_SyncMLBody extends Horde_SyncML_ContentHandler { - - var $_currentCmdID = 1; - - var $_currentCommand; - - var $_actionCommands = false; - - var $_clientSentFinal = false; - - function startElement($uri, $element, $attrs) - { - parent::startElement($uri, $element, $attrs); - $state =& $_SESSION['SyncML.state']; - - switch ($this->_xmlStack) { - case 2: - $this->_actionCommands = false; // so far, we have not seen commands that require action from our side - $state->_sendFinal = false; - - // - $this->_output->startElement($uri, $element, $attrs); - - if ($state->getLocName()) { - if ($state->isAuthConfirmed()) { - // Right our status about the header - $status = new Horde_SyncML_Command_Status(($state->isAuthorized()) ? - RESPONSE_OK : RESPONSE_INVALID_CREDENTIALS, 'SyncHdr'); - } else { - // Right our status about the header. - $status = new Horde_SyncML_Command_Status(($state->isAuthorized()) ? - RESPONSE_AUTHENTICATION_ACCEPTED : RESPONSE_INVALID_CREDENTIALS, 'SyncHdr'); - } - } else { - // Request credentials if not sent so far - $status = new Horde_SyncML_Command_Status(RESPONSE_MISSING_CREDENTIALS, 'SyncHdr'); - } - - $status->setSourceRef($state->getSourceURI()); - $status->setTargetRef($state->getTargetURI()); - $status->setCmdRef(0); - $state->clearNumberOfElements(); - - /*$str = 'authorized=' . $state->isAuthorized(); - $str .= ' version=' . $state->getVersion(); - $str .= ' msgid=' . $state->getMsgID(); - $str .= ' source=' . $state->getSourceURI(); - $str .= ' target=' . $state->getTargetURI(); - */ - $this->_currentCmdID = $status->output($this->_currentCmdID, $this->_output); - if ($state->isAuthorized()) { - $state->AuthConfirmed(); - } - break; - - case 3: - // <[Command]> - #Horde::logMessage('SyncML['. session_id() ."]: found command $element ", __FILE__, __LINE__, PEAR_LOG_DEBUG); - $this->_currentCommand = Horde_SyncML_Command::factory($element); - $this->_currentCommand->startElement($uri, $element, $attrs); - - if ($element != 'Status' && $element != 'Map' && $element != 'Final') { - // We've got to do something! This can't be the last - // packet. - $this->_actionCommands = true; - Horde::logMessage('SyncML['. session_id() ."]: found action commands <$element> ", __FILE__, __LINE__, PEAR_LOG_DEBUG); - } - - switch ($element) - { - case 'Sync': - $state->setSyncStatus(CLIENT_SYNC_STARTED); - Horde::logMessage('SyncML['. session_id() .']: syncStatus(client sync started) ' . $state->getSyncStatus(), __FILE__, __LINE__, PEAR_LOG_DEBUG); - break; - } - break; - - default: - // <...> - $this->_currentCommand->startElement($uri, $element, $attrs); - break; - } - } - - function endElement($uri, $element) - { - $state =& $_SESSION['SyncML.state']; - - switch ($this->_xmlStack) { - case 2: - // - - Horde::logMessage('SyncML['. session_id() .']: package ----------------------- done', __FILE__, __LINE__, PEAR_LOG_DEBUG); - - if ($state->getAlert222Received() == true) { - // the Funambol specialty - if ($state->getSyncStatus() == CLIENT_SYNC_FINNISHED) { - $state->setSyncStatus(CLIENT_SYNC_ACKNOWLEDGED); - } - $state->setAlert222Received(false); - } - - if ($state->needDeviceInfo()) $this->outputGetRequest(); - - // send the sync reply - // we do still have some data to send OR - // we should reply to the Sync command - if ($state->getSyncStatus() > CLIENT_SYNC_FINNISHED && $state->getSyncStatus() < SERVER_SYNC_FINNISHED) { - $sync = new Horde_SyncML_Command_Sync(); - $this->_currentCmdID = $sync->syncToClient($this->_currentCmdID, $this->_output); - } - - // send the Final tag if possible - #if ($state->getSyncStatus() != SERVER_SYNC_DATA_PENDING && $state->getSyncStatus() != CLIENT_SYNC_STARTED) { - if ($state->getSyncStatus() >= SERVER_SYNC_FINNISHED || $state->_sendFinal) { - $final = new Horde_SyncML_Command_Final(); - $this->_currentCmdID = $final->output($this->_currentCmdID, $this->_output); - } - - $this->_output->endElement($uri, $element); - - Horde::logMessage('SyncML['. session_id() .']: syncStatus = '. $state->getSyncStatus() .', actionCommands = '. - ($this->_actionCommands ? 'True' : 'False'), __FILE__, __LINE__, PEAR_LOG_DEBUG); - - if (!$this->_actionCommands && $state->getSyncStatus() == SERVER_SYNC_FINNISHED) { - // this packet did not contain any real actions, just status and map. - // This means, we're through! The session can be closed and - // the Anchors saved for the next Sync - Horde::logMessage('SyncML['. session_id() .']: sync' . session_id() . ' completed successfully!', - __FILE__, __LINE__, PEAR_LOG_INFO); - $state->writeSyncSummary(); - $log = $state->getLog(); - $s=""; - foreach ($log as $k => $v) { - $s .= " $k=$v"; - } - if (strlen(trim($s)) == 0) { - $s = ' Both parties were already in sync'; - } - Horde::logMessage('SyncML['. session_id() .']: summary:' . $s, __FILE__, __LINE__, PEAR_LOG_INFO); - # Horde::logMessage('SyncML['. session_id() .']: destroying sync session '.session_id(), __FILE__, __LINE__, PEAR_LOG_INFO); - # // session can be closed here! - # session_unset(); - # session_destroy(); - } - - if (!$this->_actionCommands && $state->getSyncStatus() == SERVER_SYNC_ACKNOWLEDGED) { - // this packet did not contain any real actions, just status and map. - // This means, we're through! The session can be closed and - // the Anchors saved for the next Sync - Horde::logMessage('SyncML['. session_id() .']: sync' . session_id() . ' completed successfully!', - __FILE__, __LINE__, PEAR_LOG_INFO); - $state->writeSyncSummary(); - $log = $state->getLog(); - $s=""; - foreach ($log as $k => $v) { - $s .= " $k=$v"; - } - if (strlen(trim($s)) == 0) { - $s = ' Both parties were already in sync'; - } - Horde::logMessage('SyncML['. session_id() .']: summary:' . $s, __FILE__, __LINE__, PEAR_LOG_INFO); - - Horde::logMessage('SyncML['. session_id() .']: destroying sync session '.session_id(), __FILE__, __LINE__, PEAR_LOG_INFO); - // session can be closed here! - session_unset(); - session_destroy(); - } - break; - - case 3: - // - - $this->_currentCommand->endElement($uri, $element); - - switch ($element) { - case 'Final': - $this->_actionCommands = false; - - if ($state->getSyncStatus() == CLIENT_SYNC_STARTED) { - if ($state->isAuthorized() && - ($deviceInfo = $state->getClientDeviceInfo()) && - strtolower($deviceInfo['manufacturer']) == 'funambol' - && isset($deviceInfo['softwareVersion'])) { - $swversion = $deviceInfo['softwareVersion']; - if ($swversion < 1.0) { - // e.g. Mozilla plugin uses this range - $swversion = $swversion * 10; - } - if (3.0 < $swversion && $swversion < 7.0) { - // We wait for a ALERT_NEXT_MESSAGE from Funambol old clients - Horde::logMessage('SyncML['. session_id() - . "]: Special treatment for Funambol version $swversion activated", - __FILE__, __LINE__, PEAR_LOG_DEBUG); - $state->setSyncStatus(CLIENT_SYNC_FINNISHED); - } else { - $state->setSyncStatus(CLIENT_SYNC_ACKNOWLEDGED); - } - } else { - $state->setSyncStatus(CLIENT_SYNC_ACKNOWLEDGED); - } - - } elseif ($state->getSyncStatus() == SERVER_SYNC_FINNISHED) { - $state->setSyncStatus(SERVER_SYNC_ACKNOWLEDGED); - } - - $this->_clientSentFinal = true; - Horde::logMessage('SyncML['. session_id() .']: syncStatus(server sync acknowledged) ' - . $state->getSyncStatus(), __FILE__, __LINE__, PEAR_LOG_DEBUG); - break; - - default: - $this->_currentCmdID = $this->_currentCommand->output($this->_currentCmdID, $this->_output); - break; - } - - unset($this->_currentCommand); - break; - - default: - // - $this->_currentCommand->endElement($uri, $element); - break; - } - - parent::endElement($uri, $element); - } - - function characters($str) { - if (isset($this->_currentCommand)) { - $this->_currentCommand->characters($str); - } - } - - function outputGetRequest() - { - $attrs = array(); - - $state =& $_SESSION['SyncML.state']; - - $uri = $state->getURI(); - $uriMeta = $state->getURIMeta(); - - Horde::logMessage('SyncML: PreferedContentTypeClient missing, sending ', - __FILE__, __LINE__, PEAR_LOG_DEBUG); - - $this->_output->startElement($uri, 'Get', $attrs); - - $this->_output->startElement($uri, 'CmdID', $attrs); - $this->_output->characters($this->_currentCmdID); - $this->_currentCmdID++; - $this->_output->endElement($uri, 'CmdID'); - - $this->_output->startElement($uri, 'Meta', $attrs); - $this->_output->startElement($uriMeta, 'Type', $attrs); - if (is_a($this->_output, 'XML_WBXML_Encoder')) { - $this->_output->characters('application/vnd.syncml-devinf+wbxml'); - } else { - $this->_output->characters('application/vnd.syncml-devinf+xml'); - } - $this->_output->endElement($uriMeta, 'Type'); - $this->_output->endElement($uri, 'Meta'); - - $this->_output->startElement($uri, 'Item', $attrs); - $this->_output->startElement($uri, 'Target', $attrs); - $this->_output->startElement($uri, 'LocURI', $attrs); - if ($state->getVersion() == 2) { - $this->_output->characters('./devinf12'); - } elseif ($state->getVersion() == 1) { - $this->_output->characters('./devinf11'); - } else { - $this->_output->characters('./devinf10'); - } - $this->_output->endElement($uri, 'LocURI'); - $this->_output->endElement($uri, 'Target'); - $this->_output->endElement($uri, 'Item'); - - $this->_output->endElement($uri, 'Get'); - - $state->deviceInfoRequested(); - } -} diff --git a/phpgwapi/inc/horde/Horde/SyncML/Command.php b/phpgwapi/inc/horde/Horde/SyncML/Command.php deleted file mode 100644 index 123d0e0fd3..0000000000 --- a/phpgwapi/inc/horde/Horde/SyncML/Command.php +++ /dev/null @@ -1,167 +0,0 @@ - - * commands. - * - * A SyncML command is a protocol primitive. Each SyncML command specifies to - * a recipient an individual operation that is to be performed. - * - * The SyncML_Command objects are hooked into the XML parser of the - * SyncML_ContentHandler class and are reponsible for parsing a single command - * inside the SyncBody section of a SyncML message. All actions that must be - * executed for a single SyncML command are handled by these objects, by means - * of the handleCommand() method. - * - * - * Using the PEAR Log class (which need to be installed!) - * - * @link http://www.egroupware.org - * @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License - * @package api - * @subpackage horde - * @author Anthony Mills - * @author Jan Schneider - * @author Joerg Lehrke - * @copyright (c) The Horde Project (http://www.horde.org/) - * @version $Id$ - */ -include_once 'Horde/SyncML/State_egw.php'; - -class Horde_SyncML_Command { - - /** - * Name of the command, like 'Put'. - * - * Must be overwritten by a sub class. - * - * @var string - */ - var $_cmdName; - - /** - * The command ID (). - * - * @var integer - */ - var $_cmdID; - - /** - * Stack for holding the XML elements during creation of the object from - * the XML event flow. - * - * @var array - */ - var $_stack = array(); - - /** - * Buffer for the parsed character data. - * - * @var string - */ - var $_chars = ''; - - /** - * Start element handler for the XML parser, delegated from - * SyncML_ContentHandler::startElement(). - * - * @param string $uri The namespace URI of the element. - * @param string $element The element tag name. - * @param array $attrs A hash with the element's attributes. - */ - function startElement($uri, $element, $attrs) - { - $this->_stack[] = $element; - } - - /** - * End element handler for the XML parser, delegated from - * SyncML_ContentHandler::endElement(). - * - * @param string $uri The namespace URI of the element. - * @param string $element The element tag name. - */ - function endElement($uri, $element) - { - if (count($this->_stack) == 2 && - $element == 'CmdID') { - $this->_cmdID = intval(trim($this->_chars)); - } - - if (strlen($this->_chars)) { - $this->_chars = ''; - } - - array_pop($this->_stack); - } - - /** - * Character data handler for the XML parser, delegated from - * SyncML_ContentHandler::characters(). - * - * @param string $str The data string. - */ - function characters($str) - { - if (isset($this->_chars)) { - $this->_chars .= $str; - } else { - $this->_chars = $str; - } - } - - /** - * Returns the command name this instance is reponsible for. - * - * @return string The command name this object is handling. - */ - function getCommandName() - { - return $this->_cmdName; - } - - /** - * This method is supposed to implement the actual business logic of the - * command once the XML parsing is complete. - * - * @abstract - */ - function output($currentCmdID, &$output) - { - } - - /** - * Attempts to return a concrete Horde_SyncML_Command instance based on - * $command. - * - * @param string $command The type of the concrete - * SyncML_Comment subclass to - * return. - * @param $params Optional Parameter. - * - * @return SyncML_Command The newly created concrete SyncML_Command - * instance, or false on error. - */ - function &factory($command, $params = null) - { - $command = basename($command); - $class = 'Horde_SyncML_Command_' . $command; - - if (!class_exists($class)) { - include_once 'Horde/SyncML/Command/' . $command . '.php'; - } - if (class_exists($class)) { - $cmd = new $class($params); - if (empty($cmd->_cmdName)) $cmd->_cmdName = $command; - } else { - $msg = 'SyncML: Class definition of ' . $class . ' not found.'; - Horde::logMessage($msg, __FILE__, __LINE__, PEAR_LOG_ERR); - require_once 'PEAR.php'; - $cmd = PEAR::raiseError($msg); - } - - return $cmd; - } - -} diff --git a/phpgwapi/inc/horde/Horde/SyncML/Command/Alert.php b/phpgwapi/inc/horde/Horde/SyncML/Command/Alert.php deleted file mode 100644 index 1327a66add..0000000000 --- a/phpgwapi/inc/horde/Horde/SyncML/Command/Alert.php +++ /dev/null @@ -1,466 +0,0 @@ - - * @author Joerg Lehrke - * @copyright (c) The Horde Project (http://www.horde.org/) - * @version $Id$ - */ -include_once 'Horde/SyncML/State_egw.php'; -include_once 'Horde/SyncML/Command.php'; - -class Horde_SyncML_Command_Alert extends Horde_SyncML_Command { - - /** - * Name of the command. - * - * @var string - */ - var $_cmdName = 'Alert'; - - /** - * The alert type. Should be one of the ALERT_* constants. - * - * @var integer - */ - var $_alert; - - /** - * Source database of the Alert command. - * - * @var string - */ - var $_sourceLocURI; - - /** - * Target database of the Alert command. - * - * @var string - */ - var $_targetLocURI; - - /** - * Optional parameter for the Target database. - * - * @var string - */ - var $_targetLocURIParameters; - - /** - * The current time this synchronization happens, from the - * element. - * - * @var string - */ - var $_metaAnchorNext; - - /** - * The last time when synchronization happened, from the - * element. - * - * @var integer - */ - var $_metaAnchorLast; - - /** - * The filter expression the client provided - * (e.g. the time range for calendar synchronization) - * - * @var string - */ - var $_filterExpression = ''; - - - /** - * Creates a new instance of Alert. - */ - function Horde_SyncML_Command_Alert($alert = null) - { - if ($alert != null) { - $this->_alert = $alert; - } - } - - function output($currentCmdID, &$output) - { - global $registry; - - $attrs = array(); - - $state = &$_SESSION['SyncML.state']; - - // Handle unauthorized first. - if (!$state->isAuthorized()) { - $status = new Horde_SyncML_Command_Status(RESPONSE_INVALID_CREDENTIALS, 'Alert'); - $status->setCmdRef($this->_cmdID); - $currentCmdID = $status->output($currentCmdID, $output); - return $currentCmdID; - } - - $type = $this->_targetLocURI; - - $clientAnchorNext = $this->_metaAnchorNext; - - if ($this->_alert == ALERT_TWO_WAY || - $this->_alert == ALERT_ONE_WAY_FROM_CLIENT || - $this->_alert == ALERT_ONE_WAY_FROM_SERVER) { - // Check if we have information about previous sync. - $info = $state->getSyncSummary($this->_targetLocURI); - if (is_a($info, 'DataTreeObject')) { - $x = $info->get('ClientAnchor'); - $clientlast = $x[$type]; - $x = $info->get('ServerAnchor'); - $serverAnchorLast = $x[$type]; - } elseif (is_array($info)) { - $clientlast = $info['ClientAnchor']; - $serverAnchorLast = $info['ServerAnchor']; - } else { - $clientlast = false; - $serverAnchorLast = 0; - } - $state->setServerAnchorLast($type, $serverAnchorLast); - - if ($clientlast !== false){ - // Info about previous successful sync sessions found. - Horde::logMessage('SyncML: Previous sync found for target ' . $type - . '; client timestamp: ' . $clientlast, - __FILE__, __LINE__, PEAR_LOG_DEBUG); - - // Check if anchor sent from client matches our own stored - // data. - if ($clientlast == $this->_metaAnchorLast) { - // Last sync anchors match, TwoWaySync will do. - $anchormatch = true; - Horde::logMessage('SyncML: Anchor timestamps match, TwoWaySync possible. Syncing data since ' - . date('Y-m-d H:i:s', $serverAnchorLast), - __FILE__, __LINE__, PEAR_LOG_DEBUG); - } else { - // Server and client have different anchors, enforce - // SlowSync/RefreshSync - Horde::logMessage('SyncML: Client requested sync with anchor timestamp ' - . $this->_metaAnchorLast - . ' but server has recorded timestamp ' - . $clientlast . '. Enforcing SlowSync', - __FILE__, __LINE__, PEAR_LOG_INFO); - $anchormatch = false; - $clientlast = 0; - } - } else { - // No info about previous sync, use SlowSync or RefreshSync. - Horde::logMessage('SyncML: No info about previous syncs found for device ' . - $state->getSourceURI() . ' and target ' . $type, - __FILE__, __LINE__, PEAR_LOG_DEBUG); - $clientlast = 0; - $serverAnchorLast = 0; - $anchormatch = false; - } - } else { - // SlowSync requested, no anchor check required. - $anchormatch = true; - } - - // Determine sync type and status response code. - Horde::logMessage("SyncML: Alert " . $this->_alert, __FILE__, __LINE__, PEAR_LOG_DEBUG); - switch ($this->_alert) { - case ALERT_NEXT_MESSAGE: - $state->setAlert222Received(true); - case ALERT_RESULT_ALERT: - case ALERT_NO_END_OF_DATA: - // Nothing to do on our side - $status = new Horde_SyncML_Command_Status(RESPONSE_OK, 'Alert'); - $status->setCmdRef($this->_cmdID); - if ($this->_sourceLocURI != null) { - $status->setSourceRef($this->_sourceLocURI); - } - if ($this->_targetLocURI != null) { - $status->setTargetRef((isset($this->_targetLocURIParameters) ? $this->_targetLocURI.'?/'.$this->_targetLocURIParameters : $this->_targetLocURI)); - } - if ($this->_alert == ALERT_NEXT_MESSAGE) { - if ($this->_sourceLocURI != null) { - $status->setItemSourceLocURI($this->_sourceLocURI); - } - if ($this->_targetLocURI != null) { - $status->setItemTargetLocURI(isset($this->_targetLocURIParameters) ? $this->_targetLocURI.'?/'.$this->_targetLocURIParameters : $this->_targetLocURI); - } - } - $currentCmdID = $status->output($currentCmdID, $output); - return $currentCmdID; - case ALERT_TWO_WAY: - if ($anchormatch) { - $synctype = ALERT_TWO_WAY; - $response = RESPONSE_OK; - } else { - $synctype = ALERT_SLOW_SYNC; - $response = RESPONSE_REFRESH_REQUIRED; - } - break; - - case ALERT_SLOW_SYNC: - $synctype = ALERT_SLOW_SYNC; - $response = $anchormatch ? RESPONSE_OK : RESPONSE_REFRESH_REQUIRED; - break; - - case ALERT_ONE_WAY_FROM_CLIENT: - if ($anchormatch) { - $synctype = ALERT_ONE_WAY_FROM_CLIENT; - $response = RESPONSE_OK; - } else { - $synctype = ALERT_REFRESH_FROM_CLIENT; - $response = RESPONSE_REFRESH_REQUIRED; - } - break; - - case ALERT_REFRESH_FROM_CLIENT: - $synctype = ALERT_REFRESH_FROM_CLIENT; - $response = $anchormatch ? RESPONSE_OK : RESPONSE_REFRESH_REQUIRED; - - // We will erase the current server content, - // then we can add the client's contents. - - $hordeType = $state->getHordeType($this->_targetLocURI); - - $state->setTargetURI($this->_targetLocURI); - $deletes = $state->getClientItems(); - if (is_array($deletes)) { - foreach ($deletes as $delete) { - $registry->call($hordeType . '/delete', array($delete)); - } - Horde::logMessage("SyncML: RefreshFromClient " . count($deletes) . " entries deleted for $hordeType", __FILE__, __LINE__, PEAR_LOG_DEBUG); - } - $anchormatch = false; - break; - - case ALERT_ONE_WAY_FROM_SERVER: - if ($anchormatch) { - $synctype = ALERT_ONE_WAY_FROM_SERVER; - $response = RESPONSE_OK; - } else { - $synctype = ALERT_REFRESH_FROM_SERVER; - $response = RESPONSE_REFRESH_REQUIRED; - } - break; - - case ALERT_REFRESH_FROM_SERVER: - $synctype = ALERT_REFRESH_FROM_SERVER; - $response = $anchormatch ? RESPONSE_OK : RESPONSE_REFRESH_REQUIRED; - $anchormatch = false; - break; - - case ALERT_RESUME: - // @TODO: Suspend and Resume is not supported yet - $synctype = ALERT_SLOW_SYNC; - $response = RESPONSE_REFRESH_REQUIRED; - break; - - default: - // We can't handle this one - Horde::logMessage('SyncML: Unknown sync type ' . $this->_alert, - __FILE__, __LINE__, PEAR_LOG_ERR); - $status = new Horde_SyncML_Command_Status(RESPONSE_BAD_REQUEST, 'Alert'); - $status->setCmdRef($this->_cmdID); - if ($this->_sourceLocURI != null) { - $status->setSourceRef($this->_sourceLocURI); - } - if ($this->_targetLocURI != null) { - $status->setTargetRef((isset($this->_targetLocURIParameters) ? $this->_targetLocURI.'?/'.$this->_targetLocURIParameters : $this->_targetLocURI)); - } - $currentCmdID = $status->output($currentCmdID, $output); - return $currentCmdID; - } - - // Now set interval to retrieve server changes from, defined by - // ServerAnchor [Last,Next] - if ($synctype != ALERT_TWO_WAY && - $synctype != ALERT_ONE_WAY_FROM_CLIENT && - $synctype != ALERT_ONE_WAY_FROM_SERVER) { - $serverAnchorLast = 0; - if (isset($GLOBALS['egw_info']['user']['preferences']['syncml']['slowsync_ignore_map']) && - $GLOBALS['egw_info']['user']['preferences']['syncml']['slowsync_ignore_map'] - || !$anchormatch) { - // Erase existing map - $state->removeAllUID($this->_targetLocURI); - } - } - // Now create the actual SyncML_Sync object, if it doesn't exist yet. - $sync = &$state->getSync($this->_targetLocURI); - if (!$sync) { - Horde::logMessage('SyncML: Creating SyncML_Sync object for target ' - . $this->_targetLocURI . '; sync type ' . $synctype, - __FILE__, __LINE__, PEAR_LOG_DEBUG); - $sync = &Horde_SyncML_Sync::factory($synctype); - $state->clearConflictItems($this->_targetLocURI); - } - $sync->setTargetLocURI($this->_targetLocURI); - $sync->setSourceLocURI($this->_sourceLocURI); - $sync->setLocName($state->getLocName()); // We need it for conflict handling - $sync->setsyncType($synctype); - $sync->setFilterExpression($this->_filterExpression); - $state->setSync($this->_targetLocURI, $sync); - $hordeType = $state->getHordeType($this->_targetLocURI); - $changes =& $registry->call($hordeType. '/listBy', - array('action' => 'modify', - 'timestamp' => $serverAnchorLast, - 'type' => $this->_targetLocURI, - 'filter' => $this->_filterExpression)); - $state->setChangedItems($this->_targetLocURI, $changes); - - // Store client's Next Anchor in State and - // set server's Next Anchor. After successful sync - // this is then written to persistence for negotiation of - // further syncs. - $state->setClientAnchorNext($type, $this->_metaAnchorNext); - $serverAnchorNext = time(); - $state->setServerAnchorNext($type, $serverAnchorNext); - - $status = new Horde_SyncML_Command_Status($response, 'Alert'); - $status->setCmdRef($this->_cmdID); - if ($this->_sourceLocURI != null) { - $status->setSourceRef($this->_sourceLocURI); - } - if ($this->_targetLocURI != null) { - $status->setTargetRef((isset($this->_targetLocURIParameters) ? $this->_targetLocURI.'?/'.$this->_targetLocURIParameters : $this->_targetLocURI)); - } - - // Mirror Next Anchor from client back to client. - if (isset($this->_metaAnchorNext)) { - $status->setItemDataAnchorNext($this->_metaAnchorNext); - } - - // Mirror Last Anchor from client back to client. - if (isset($this->_metaAnchorLast)) { - $status->setItemDataAnchorLast($this->_metaAnchorLast); - } - - $currentCmdID = $status->output($currentCmdID, $output); - - $output->startElement($state->getURI(), 'Alert', $attrs); - - $output->startElement($state->getURI(), 'CmdID', $attrs); - $chars = $currentCmdID; - $output->characters($chars); - $output->endElement($state->getURI(), 'CmdID'); - - $output->startElement($state->getURI(), 'Data', $attrs); - $chars = $synctype; - $output->characters($chars); - $output->endElement($state->getURI(), 'Data'); - - $output->startElement($state->getURI(), 'Item', $attrs); - - if ($this->_sourceLocURI != null) { - $output->startElement($state->getURI(), 'Target', $attrs); - $output->startElement($state->getURI(), 'LocURI', $attrs); - $chars = $this->_sourceLocURI; - $output->characters($chars); - $output->endElement($state->getURI(), 'LocURI'); - $output->endElement($state->getURI(), 'Target'); - } - - if ($this->_targetLocURI != null) { - $output->startElement($state->getURI(), 'Source', $attrs); - $output->startElement($state->getURI(), 'LocURI', $attrs); - $chars = (isset($this->_targetLocURIParameters) ? $this->_targetLocURI.'?/'.$this->_targetLocURIParameters : $this->_targetLocURI); - $output->characters($chars); - $output->endElement($state->getURI(), 'LocURI'); - $output->endElement($state->getURI(), 'Source'); - } - - $output->startElement($state->getURI(), 'Meta', $attrs); - - $output->startElement($state->getURIMeta(), 'Anchor', $attrs); - - $output->startElement($state->getURIMeta(), 'Last', $attrs); - $chars = $state->getServerAnchorLast($type); - $output->characters($chars ? $chars : '0'); // Some devices don't like empty anchors - $output->endElement($state->getURIMeta(), 'Last'); - - $output->startElement($state->getURIMeta(), 'Next', $attrs); - $chars = $state->getServerAnchorNext($type); - $output->characters($chars); - $output->endElement($state->getURIMeta(), 'Next'); - - $output->endElement($state->getURIMeta(), 'Anchor'); - $output->endElement($state->getURI(), 'Meta'); - $output->endElement($state->getURI(), 'Item'); - $output->endElement($state->getURI(), 'Alert'); - - // Final packet of this message - $state->_sendFinal = true; - - $currentCmdID++; - - return $currentCmdID; - } - - /** - * End element handler for the XML parser, delegated from - * SyncML_ContentHandler::endElement(). - * - * @param string $uri The namespace URI of the element. - * @param string $element The element tag name. - */ - function endElement($uri, $element) - { - switch (count($this->_stack)) { - case 2: - if ($element == 'Data') { - $this->_alert = intval(trim($this->_chars)); - } - break; - - case 4: - if ($element == 'LocURI') { - switch ($this->_stack[2]) { - case 'Source': - $this->_sourceLocURI = trim($this->_chars); - break; - case 'Target': - $targetLocURIData = explode('?/',trim($this->_chars)); - - $this->_targetLocURI = $targetLocURIData[0]; - - if (isset($targetLocURIData[1])) { - $this->_targetLocURIParameters = $targetLocURIData[1]; - } - break; - } - } - break; - - case 5: - switch ($element) { - case 'Next': - $this->_metaAnchorNext = trim($this->_chars); - break; - case 'Last': - $this->_metaAnchorLast = trim($this->_chars); - break; - } - break; - - case 7: - if ($element == 'Data' - && $this->_stack[2] == 'Target' - && $this->_stack[3] == 'Filter' - && $this->_stack[4] == 'Record' - && $this->_stack[5] == 'Item') { - $this->_filterExpression = trim($this->_chars); - } - break; - } - parent::endElement($uri, $element); - } - -} diff --git a/phpgwapi/inc/horde/Horde/SyncML/Command/Final.php b/phpgwapi/inc/horde/Horde/SyncML/Command/Final.php deleted file mode 100644 index 0066137665..0000000000 --- a/phpgwapi/inc/horde/Horde/SyncML/Command/Final.php +++ /dev/null @@ -1,41 +0,0 @@ - - * @copyright (c) The Horde Project (http://www.horde.org/) - * @version $Id$ - */ -include_once 'Horde/SyncML/Command.php'; - -class Horde_SyncML_Command_Final extends Horde_SyncML_Command { - - /** - * Name of the command. - * - * @var string - */ - var $_cmdName = 'Final'; - - function output($currentCmdID, &$output) - { - $state = $_SESSION['SyncML.state']; - - $attrs = array(); - $output->startElement($state->getURI(), 'Final', $attrs); - - $output->endElement($state->getURI(), 'Final'); - - return $currentCmdID; - } - -} diff --git a/phpgwapi/inc/horde/Horde/SyncML/Command/Get.php b/phpgwapi/inc/horde/Horde/SyncML/Command/Get.php deleted file mode 100644 index 49de9cdcdf..0000000000 --- a/phpgwapi/inc/horde/Horde/SyncML/Command/Get.php +++ /dev/null @@ -1,247 +0,0 @@ - - * @author Karsten Fourmont - * @author Joerg Lehrke - * @copyright (c) The Horde Project (http://www.horde.org/) - * @version $Id$ - */ -include_once 'Horde/SyncML/State.php'; -include_once 'Horde/SyncML/Command.php'; -include_once 'Horde/SyncML/Command/Results.php'; - -class Horde_SyncML_Command_Get extends Horde_SyncML_Command { - - /** - * Name of the command. - * - * @var string - */ - var $_cmdName = 'Get'; - - function output($currentCmdID, &$output) - { - $state = $_SESSION['SyncML.state']; - - if ($state->getVersion() == 2) { - $ref = './devinf12'; - } elseif ($state->getVersion() == 1) { - $ref = './devinf11'; - } else { - $ref = './devinf10'; - } - - $status = new Horde_SyncML_Command_Status((($state->isAuthorized()) ? RESPONSE_OK : RESPONSE_INVALID_CREDENTIALS), $this->_cmdName); - $status->setCmdRef($this->_cmdID); - $status->setTargetRef($ref); - $currentCmdID = $status->output($currentCmdID, $output); - - if ($state->isAuthorized()) { - $attrs = array(); - $output->startElement($state->getURI(), 'Results', $attrs); - - $output->startElement($state->getURI(), 'CmdID', $attrs); - $chars = $currentCmdID; - $output->characters($chars); - $output->endElement($state->getURI(), 'CmdID'); - - $output->startElement($state->getURI(), 'MsgRef', $attrs); - $chars = $state->getMsgID(); - $output->characters($chars); - $output->endElement($state->getURI(), 'MsgRef'); - - $output->startElement($state->getURI(), 'CmdRef', $attrs); - $chars = $this->_cmdID; - $output->characters($chars); - $output->endElement($state->getURI(), 'CmdRef'); - - $output->startElement($state->getURI(), 'Meta', $attrs); - $output->startElement($state->getURIMeta(), 'Type', $attrs); - if (is_a($output, 'XML_WBXML_Encoder')) { - $output->characters(MIME_SYNCML_DEVICE_INFO_WBXML); - } else { - $output->characters(MIME_SYNCML_DEVICE_INFO_XML); - } - - $output->endElement($state->getURIMeta(), 'Type'); - $output->endElement($state->getURI(), 'Meta'); - - $output->startElement($state->getURI(), 'Item', $attrs); - $output->startElement($state->getURI(), 'Source', $attrs); - $output->startElement($state->getURI(), 'LocURI', $attrs); - $output->characters($ref); - $output->endElement($state->getURI(), 'LocURI'); - $output->endElement($state->getURI(), 'Source'); - - $output->startElement($state->getURI(), 'Data', $attrs); - - $output->startElement($state->getURIDevInf() , 'DevInf', $attrs); - $output->startElement($state->getURIDevInf() , 'VerDTD', $attrs); - if ($state->getVersion() == 2) { - $output->characters('1.2'); - } elseif($state->getVersion() == 1) { - $output->characters('1.1'); - } else { - $output->characters('1.0'); - } - $output->endElement($state->getURIDevInf() , 'VerDTD', $attrs); - $output->startElement($state->getURIDevInf() , 'Man', $attrs); - $output->characters('www.egroupware.org'); - $output->endElement($state->getURIDevInf() , 'Man', $attrs); - $output->startElement($state->getURIDevInf() , 'Mod', $attrs); - $output->characters('DS Server'); - $output->endElement($state->getURIDevInf() , 'Mod', $attrs); - $output->startElement($state->getURIDevInf() , 'OEM', $attrs); - $output->characters('-'); - $output->endElement($state->getURIDevInf() , 'OEM', $attrs); - $output->startElement($state->getURIDevInf() , 'FwV', $attrs); - $output->characters('-'); - $output->endElement($state->getURIDevInf() , 'FwV', $attrs); - $output->startElement($state->getURIDevInf() , 'SwV', $attrs); - $output->characters('1.7.x'); - $output->endElement($state->getURIDevInf() , 'SwV', $attrs); - $output->startElement($state->getURIDevInf() , 'HwV', $attrs); - $output->characters('-'); - $output->endElement($state->getURIDevInf() , 'HwV', $attrs); - $output->startElement($state->getURIDevInf() , 'DevID', $attrs); - $output->characters($_SERVER['HTTP_HOST']); - $output->endElement($state->getURIDevInf() , 'DevID', $attrs); - $output->startElement($state->getURIDevInf() , 'DevTyp', $attrs); - $output->characters('server'); - $output->endElement($state->getURIDevInf() , 'DevTyp', $attrs); - $output->startElement($state->getURIDevInf() , 'UTC', $attrs); - $output->endElement($state->getURIDevInf() , 'UTC', $attrs); - $output->startElement($state->getURIDevInf() , 'SupportNumberOfChanges', $attrs); - $output->endElement($state->getURIDevInf() , 'SupportNumberOfChanges', $attrs); - $output->startElement($state->getURIDevInf() , 'SupportLargeObjs', $attrs); - $output->endElement($state->getURIDevInf() , 'SupportLargeObjs', $attrs); - $this->_writeDataStore('notes', 'text/x-vnote', '1.1', $output, - array('text/plain' => '1.0')); - $this->_writeDataStore('contacts', 'text/vcard', '3.0', $output, - array('text/x-vcard' => '2.1')); - $this->_writeDataStore('card', 'text/vcard', '3.0', $output, - array('text/x-vcard' => '2.1')); - $this->_writeDataStore('tasks', 'text/calendar', '2.0', $output, - array('text/x-vcalendar' => '1.0')); - $this->_writeDataStore('jobs', 'text/calendar', '2.0', $output, - array('text/x-vcalendar' => '1.0')); - $this->_writeDataStore('calendar', 'text/calendar', '2.0', $output, - array('text/x-vcalendar' => '1.0')); - $this->_writeDataStore('events', 'text/calendar', '2.0', $output, - array('text/x-vcalendar' => '1.0')); - $this->_writeDataStore('caltasks', 'text/calendar', '2.0', $output, - array('text/x-vcalendar' => '1.0')); - // Funambol special Datastore - $this->_writeDataStore('configuration', 'text/plain', '1.0', $output); - $output->endElement($state->getURIDevInf() , 'DevInf', $attrs); - - $output->endElement($state->getURI(), 'Data'); - $output->endElement($state->getURI(), 'Item'); - $output->endElement($state->getURI(), 'Results'); - /* - $output->startElement($state->getURIDevInf() , 'Ext', $attrs); - $output->startElement($state->getURIDevInf() , 'XNam', $attrs); - $output->characters('X-funambol-smartslow'); - $output->endElement($state->getURIDevInf() , 'XNam', $attrs); - $output->endElement($state->getURIDevInf() , 'Ext', $attrs); - */ - $currentCmdID++; - } - - return $currentCmdID; - } - - /** - * Writes DevInf data for one DataStore. - * - * @param string $sourceref: data for SourceRef element. - * @param string $mimetype: data for <(R|T)x-Pref><CTType> - * @param string $version: data for <(R|T)x-Pref><VerCT> - * @param string &$output contenthandler that will received the output. - * @param array $additionaltypes: array of additional types for Tx and Rx; - * format array('text/vcard' => '3.0') - */ - function _writeDataStore($sourceref, $mimetype, $version, &$output, - $additionaltypes = false) - { - $attrs = array(); - - $state = &$_SESSION['SyncML.state']; - - $output->startElement($state->getURIDevInf() , 'DataStore', $attrs); - $output->startElement($state->getURIDevInf() , 'SourceRef', $attrs); - $output->characters($sourceref); - $output->endElement($state->getURIDevInf() , 'SourceRef', $attrs); - $output->startElement($state->getURIDevInf() , 'DisplayName', $attrs); - $output->characters($sourceref); - $output->endElement($state->getURIDevInf() , 'DisplayName', $attrs); - $output->startElement($state->getURIDevInf() , 'MaxGUIDSize', $attrs); - $output->characters(255); - $output->endElement($state->getURIDevInf() , 'MaxGUIDSize', $attrs); - - $output->startElement($state->getURIDevInf() , 'Rx-Pref', $attrs); - $output->startElement($state->getURIDevInf() , 'CTType', $attrs); - $output->characters($mimetype); - $output->endElement($state->getURIDevInf() , 'CTType', $attrs); - $output->startElement($state->getURIDevInf() , 'VerCT', $attrs); - $output->characters($version); - $output->endElement($state->getURIDevInf() , 'VerCT', $attrs); - $output->endElement($state->getURIDevInf() , 'Rx-Pref', $attrs); - - if (is_array($additionaltypes)) { - foreach ($additionaltypes as $ct => $ctver){ - $output->startElement($state->getURIDevInf() , 'Rx', $attrs); - $output->startElement($state->getURIDevInf() , 'CTType', $attrs); - $output->characters($ct); - $output->endElement($state->getURIDevInf() , 'CTType', $attrs); - $output->startElement($state->getURIDevInf() , 'VerCT', $attrs); - $output->characters($ctver); - $output->endElement($state->getURIDevInf() , 'VerCT', $attrs); - $output->endElement($state->getURIDevInf() , 'Rx', $attrs); - } - } - - $output->startElement($state->getURIDevInf() , 'Tx-Pref', $attrs); - $output->startElement($state->getURIDevInf() , 'CTType', $attrs); - $output->characters($mimetype); - $output->endElement($state->getURIDevInf() , 'CTType', $attrs); - $output->startElement($state->getURIDevInf() , 'VerCT', $attrs); - $output->characters($version); - $output->endElement($state->getURIDevInf() , 'VerCT', $attrs); - $output->endElement($state->getURIDevInf() , 'Tx-Pref', $attrs); - - if (is_array($additionaltypes)) { - foreach ($additionaltypes as $ct => $ctver){ - $output->startElement($state->getURIDevInf() , 'Tx', $attrs); - $output->startElement($state->getURIDevInf() , 'CTType', $attrs); - $output->characters($ct); - $output->endElement($state->getURIDevInf() , 'CTType', $attrs); - $output->startElement($state->getURIDevInf() , 'VerCT', $attrs); - $output->characters($ctver); - $output->endElement($state->getURIDevInf() , 'VerCT', $attrs); - $output->endElement($state->getURIDevInf() , 'Tx', $attrs); - } - } - - $output->startElement($state->getURIDevInf() , 'SyncCap', $attrs); - // We support all sync Types from 1-6: two way, slow, refresh|update - // from client|server - for ($i = 1; $i <= 6; ++$i) { - $output->startElement($state->getURIDevInf(), 'SyncType', $attrs); - $output->characters($i); - $output->endElement($state->getURIDevInf(), 'SyncType', $attrs); - } - $output->endElement($state->getURIDevInf() , 'SyncCap', $attrs); - $output->endElement($state->getURIDevInf() , 'DataStore', $attrs); - } - -} diff --git a/phpgwapi/inc/horde/Horde/SyncML/Command/Map.php b/phpgwapi/inc/horde/Horde/SyncML/Command/Map.php deleted file mode 100644 index 17dd7e44fa..0000000000 --- a/phpgwapi/inc/horde/Horde/SyncML/Command/Map.php +++ /dev/null @@ -1,141 +0,0 @@ - - * @copyright (c) The Horde Project (http://www.horde.org/) - * @version $Id$ - */ -include_once 'Horde/SyncML/State.php'; -include_once 'Horde/SyncML/Command.php'; - -class Horde_SyncML_Command_Map extends Horde_SyncML_Command { - - /** - * Name of the command. - * - * @var string - */ - var $_cmdName = 'Map'; - - /** - * Source database of the Map command. - * - * @var string - */ - var $_sourceLocURI; - - /** - * Target database of the Map command. - * - * @var string - */ - var $_targetLocURI; - - /** - * Recipient map item specifier. - * - * @var string - */ - var $_mapTarget; - - /** - * Originator map item specifier. - * - * @var string - */ - var $_mapSource; - - function output($currentCmdID, &$output) - { - $attrs = array(); - - $state = $_SESSION['SyncML.state']; - - $status = new Horde_SyncML_Command_Status($state->isAuthorized() ? RESPONSE_OK : RESPONSE_INVALID_CREDENTIALS, 'Map'); - $status->setCmdRef($this->_cmdID); - if ($this->_sourceLocURI != null) { - $status->setSourceRef($this->_sourceLocURI); - } - if ($this->_targetLocURI != null) { - $status->setTargetRef($this->_targetLocURI); - } - - $currentCmdID = $status->output($currentCmdID, $output); - - return $currentCmdID; - } - - function startElement($uri, $element, $attrs) - { - parent::startElement($uri, $element, $attrs); - - if (count($this->_stack) == 2 && - $element == 'MapItem') { - unset($this->_mapTarget); - unset($this->_mapSource); - } - } - - function endElement($uri, $element) - { - - $state = &$_SESSION['SyncML.state']; - - switch (count($this->_stack)) { - case 2: - if ($element == 'MapItem') { - $sync = $state->getSync($this->_targetLocURI); - if (!$state->isAuthorized()) { - Horde::logMessage('SyncML: Not Authorized in the middle of MapItem!', __FILE__, __LINE__, PEAR_LOG_ERR); - } else { - Horde::logMessage("SyncML: creating Map for source=" . - $this->_mapSource . " and target=" . $this->_mapTarget, __FILE__, __LINE__, PEAR_LOG_DEBUG); - // Overwrite existing data by removing it first: - $ts = $state->getServerAnchorNext($this->_targetLocURI); - $r = $state->setUID($this->_targetLocURI, $this->_mapSource, $this->_mapTarget, $ts); - if (is_a($r, 'PEAR_Error')) { - Horde::logMessage('SyncML: PEAR Error: ' . $r->getMessage(), __FILE__, __LINE__, PEAR_LOG_ERR); - return false; - } - } - } - break; - - case 3: - if ($element == 'LocURI') { - if ($this->_stack[1] == 'Source') { - $this->_sourceLocURI = trim($this->_chars); - } elseif ($this->_stack[1] == 'Target') { - $targetLocURIData = explode('?/',trim($this->_chars)); - $this->_targetLocURI = $targetLocURIData[0]; - } - } - break; - - case 4: - if ($element == 'LocURI') { - if ($this->_stack[2] == 'Source') { - $this->_mapSource = trim($this->_chars); - } elseif ($this->_stack[2] == 'Target') { - $this->_mapTarget = trim($this->_chars); - } - } - break; - } - - parent::endElement($uri, $element); - } - -} diff --git a/phpgwapi/inc/horde/Horde/SyncML/Command/Put.php b/phpgwapi/inc/horde/Horde/SyncML/Command/Put.php deleted file mode 100644 index a1bcc14251..0000000000 --- a/phpgwapi/inc/horde/Horde/SyncML/Command/Put.php +++ /dev/null @@ -1,364 +0,0 @@ - - * @author Joerg Lehrke - * @copyright (c) The Horde Project (http://www.horde.org/) - * @version $Id$ - */ -include_once 'Horde/SyncML/State.php'; -include_once 'Horde/SyncML/Command.php'; - -class Horde_SyncML_Command_Put extends Horde_SyncML_Command { - - /** - * Name of the command. - * - * @var string - */ - var $_cmdName = 'Put'; - - /** - * @var string $_manufacturer - */ - - var $_manufacturer; - - /** - * @var string $_model - */ - - var $_model; - - /** - * @var string $_oem - */ - - var $_oem; - - /** - * @var array $_deviceInfo - */ - - var $_deviceInfo; - - /** - * @var string $_softwareVersion - */ - - var $_softwareVersion; - - function endElement($uri, $element) { - switch (count($this->_stack)) { - case 5: - switch ($element) { - case 'DataStore': - $this->_deviceInfo['dataStore'][$this->_sourceReference] = array ( - 'maxGUIDSize' => $this->_maxGUIDSize, - 'rxPreference' => $this->_rxPreference, - 'txPreference' => $this->_txPreference, - 'syncCapabilities' => $this->_syncCapabilities, - 'properties' => $this->_properties, - ); - break; - - case 'DevID': - $this->_deviceInfo['deviceID'] = trim($this->_chars); - break; - - case 'DevTyp': - $this->_deviceInfo['deviceType'] = trim($this->_chars); - break; - - case 'FwV': - $this->_deviceInfo['firmwareVersion'] = trim($this->_chars); - break; - - case 'HwV': - $this->_deviceInfo['hardwareVersion'] = trim($this->_chars); - break; - - case 'Man': - $this->_deviceInfo['manufacturer'] = trim($this->_chars); - break; - - case 'Mod': - $this->_deviceInfo['model'] = trim($this->_chars); - break; - - case 'OEM': - $this->_deviceInfo['oem'] = trim($this->_chars); - break; - - case 'SwV': - $this->_deviceInfo['softwareVersion'] = trim($this->_chars); - break; - - case 'SupportLargeObjs': - $this->_deviceInfo['supportLargeObjs'] = true; - break; - - case 'SupportNumberOfChanges': - $this->_deviceInfo['supportNumberOfChanges'] = true; - break; - - case 'UTC': - $this->_deviceInfo['UTC'] = true; - break; - - case 'VerDTD': - $this->_deviceInfo['DTDVersion'] = trim($this->_chars); - break; - } - break; - case 6: - switch($element) { - case 'MaxGUIDSize': - $this->_maxGUIDSize = trim($this->_chars); - break; - - case 'Rx-Pref': - $this->_rxPreference = array( - 'contentType' => $this->_contentType, - 'contentVersion' => $this->_contentVersion, - ); - break; - - case 'SourceRef': - $this->_sourceReference = strtolower(trim($this->_chars)); - break; - - case 'Tx-Pref': - $this->_txPreference = array( - 'contentType' => $this->_contentType, - 'contentVersion' => $this->_contentVersion, - ); - break; - } - break; - - case 7: - switch($element) { - case 'CTType': - $this->_contentType = trim($this->_chars); - if (substr($this->_contentType, 0, 14) == "text/x-s4j-sif") - { - // workaround a little bug in sync4j for mobile v3.1.3 (and possibly others) - // where the content-type is set to just one value regardless of - // the source... this further leads to a failure to send updates - // by the server since it does not know how to convert say tasks to text/x-s4j-sifc - // (it should be text/x-s4j-sift). - switch ($this->_sourceReference) - { - case 'contact': - case 'card': - if ($this->_contentType != "text/x-s4j-sifc") - { - error_log("forcing 'contact' content type to 'text/x-s4j-sifc' instead of '".$this->_contentType."'"); - $this->_contentType = "text/x-s4j-sifc"; - } - break; - case 'calendar': - case 'appointment': - if ($this->_contentType != "text/x-s4j-sife") - { - error_log("forcing 'calendar' content type to 'text/x-s4j-sife' instead of '".$this->_contentType."'"); - $this->_contentType = "text/x-s4j-sife"; - } - break; - case 'task': - if ($this->_contentType != "text/x-s4j-sift") - { - error_log("forcing 'task' content type to 'text/x-s4j-sift' instead of '".$this->_contentType."'"); - $this->_contentType = "text/x-s4j-sift"; - } - break; - case 'note': - if ($this->_contentType != "text/x-s4j-sifn") - { - error_log("forcing 'note' content type to 'text/x-s4j-sifn' instead of '".$this->_contentType."'"); - $this->_contentType = "text/x-s4j-sifn"; - } - break; - default: - #error_log("Leaving ContentType='".$this->_contentType."' as is for source '".$this->_sourceReference."'"); - break; - } - } - break; - - case 'SyncType': - $this->_syncCapabilities[] = trim($this->_chars); - break; - - case 'VerCT': - $this->_contentVersion = trim($this->_chars); - break; - - case 'Property': - if (isset($this->_PropName)) { - $this->_properties[$this->_contentType][$this->_contentVersion][$this->_PropName] = array( - 'Size' => $this->_PropSize, - 'NoTruncate' => $this->_PropNoTruncate, - ); - } - break; - } - break; - - case 8: - switch($element) { - case 'PropName': - $this->_PropName = trim($this->_chars); - break; - - case 'Size': - $this->_PropSize = trim($this->_chars); - break; - - case 'NoTruncate': - $this->_PropNoTruncate = true; - break; - } - beak; - } - - parent::endElement($uri, $element); - } - - function finalizeDeviceInfo() - { - // get some more information about the device from out of band data - - $ua = $_SERVER['HTTP_USER_AGENT']; - - if (($pos = strpos($ua, 'Funambol'))!== false) { - $this->_deviceInfo['manufacturer'] = 'Funambol'; - $this->_deviceInfo['model'] = 'generic'; - $this->_deviceInfo['softwareVersion'] = 3.1; // force special treatment - $type = substr($ua, $pos + 9); - if (preg_match("/^(.*) [^\d]*(\d+\.?\d*)[\.|\d]*\s*$/i", $type, $matches)) { - // Funambol uses the hardware Manufacturer we don't care about - $this->_deviceInfo['model'] = trim($matches[1]); - $this->_deviceInfo['softwareVersion'] = floatval($matches[2]); - } - if (!isset($this->_deviceInfo['deviceType'])) { - switch (strtolower(trim($matches[1]))) { - case 'pocket pc plug-in': - $this->_deviceInfo['deviceType'] = 'windowsmobile'; - break; - case 'outlook plug-in': - default: - $this->_deviceInfo['deviceType'] = 'workstation'; - break; - } - } - - } - - switch (strtolower($this->_deviceInfo['deviceID'])) { - case 'fmz-thunderbird-plugin': - if (empty($this->_devinceInfo['manufacturer'])) { - $this->_deviceInfo['manufacturer'] = 'Funambol'; - } - if (empty($this->_devinceInfo['model'])) { - $this->_deviceInfo['model'] = 'ThunderBird'; - } - if (empty($this->_devinceInfo['softwareVersion'])) { - $this->_deviceInfo['softwareVersion'] = '3.0'; - } - break; - } - - if (preg_match('/Funambol.*/i', $this->_deviceInfo['manufacturer'])) { - $this->_deviceInfo['supportLargeObjs'] = true; - } - - switch (strtolower($this->_deviceInfo['manufacturer'])) { - case 'sonyericsson': - case 'sony ericsson': - if (strtolower($this->_deviceInfo['model']) == 'w890i') { - $this->_deviceInfo['supportLargeObjs'] = false; - } - break; - case 'synthesis ag': - foreach ($this->_deviceInfo['dataStore'] as &$ctype) { - $ctype['maxGUIDSize'] = 255; - } - break; - } - } - - function output($currentCmdID, &$output ) { - $state = &$_SESSION['SyncML.state']; - - $status = new Horde_SyncML_Command_Status((($state->isAuthorized()) ? RESPONSE_OK : RESPONSE_INVALID_CREDENTIALS), $this->_cmdName); - $status->setCmdRef($this->_cmdID); - - if ($state->getVersion() == 2) { - $ref = './devinf12'; - } elseif ($state->getVersion() == 1) { - $ref = './devinf11'; - } else { - $ref = './devinf10'; - } - - $status->setSourceRef($ref); - - if($state->isAuthorized()) { - $this->finalizeDeviceInfo(); - - if(count((array)$this->_deviceInfo) > 0) { - $devInfo = $state->getClientDeviceInfo(); - if (is_array($devInfo['dataStore']) - && $devInfo['softwareVersion'] == $this->_deviceInfo['softwareVersion']) { - // merge with existing information - $devInfo['dataStore'] = - array_merge($devInfo['dataStore'], - $this->_deviceInfo['dataStore']); - } else { - // new device - $devInfo = $this->_deviceInfo; - } - #Horde::logMessage("SyncML: Put DeviceInfo:\n" . print_r($this->_deviceInfo, true), __FILE__, __LINE__, PEAR_LOG_DEBUG); - $state->setClientDeviceInfo($devInfo); - $state->writeClientDeviceInfo(); - } - } - - return $status->output($currentCmdID, $output); - } - - function startElement($uri, $element, $attrs) { - #Horde::logMessage("SyncML: startElement[" . count($this->_stack) . "] $uri $element", __FILE__, __LINE__, PEAR_LOG_DEBUG); - switch (count($this->_stack)) { - case 4: - switch ($element) { - case 'DataStore': - $this->_properties = array(); - break; - } - break; - - case 6: - switch ($element) { - case 'Property': - unset($this->_PropName); - $this->_PropSize = -1; - $this->_PropNoTruncate = false; - break; - } - break; - } - parent::startElement($uri, $element, $attrs); - } - -} diff --git a/phpgwapi/inc/horde/Horde/SyncML/Command/Replace.php b/phpgwapi/inc/horde/Horde/SyncML/Command/Replace.php deleted file mode 100644 index 19f0751c01..0000000000 --- a/phpgwapi/inc/horde/Horde/SyncML/Command/Replace.php +++ /dev/null @@ -1,32 +0,0 @@ - - * @copyright (c) The Horde Project (http://www.horde.org/) - * @version $Id$ - */ -include_once 'Horde/SyncML/Command.php'; - -class Horde_SyncML_Command_Replace extends Horde_SyncML_Command { - - /** - * Name of the command. - * - * @var string - */ - var $_cmdName = 'Replace'; - - function output($currentCmdID, &$output) - { - return $currentCmdID; - } - -} diff --git a/phpgwapi/inc/horde/Horde/SyncML/Command/Results.php b/phpgwapi/inc/horde/Horde/SyncML/Command/Results.php deleted file mode 100644 index 2541666dc0..0000000000 --- a/phpgwapi/inc/horde/Horde/SyncML/Command/Results.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright (c) The Horde Project (http://www.horde.org/) - * @version $Id$ - */ -include_once 'Horde/SyncML/Command/Put.php'; - -class Horde_SyncML_Command_Results extends Horde_SyncML_Command_Put { - - /** - * Name of the command. - * - * @var string - */ - var $_cmdName = 'Results'; - -} diff --git a/phpgwapi/inc/horde/Horde/SyncML/Command/Status.php b/phpgwapi/inc/horde/Horde/SyncML/Command/Status.php deleted file mode 100644 index 32dfeff6ac..0000000000 --- a/phpgwapi/inc/horde/Horde/SyncML/Command/Status.php +++ /dev/null @@ -1,363 +0,0 @@ - - * @author Joerg Lehrke - * @copyright (c) The Horde Project (http://www.horde.org/) - * @version $Id$ - */ -include_once 'Horde/SyncML/State.php'; -include_once 'Horde/SyncML/Command.php'; - -class Horde_SyncML_Command_Status extends Horde_SyncML_Command { - - /** - * Name of the command. - * - * @var string - */ - var $_cmdName = 'Status'; - - /** - * The Response code of the command sent to the client, that this - * Status response refers to. - * - * @var integer - */ - var $_response; - - /** - * The command ID (CmdID) of the command sent to the client, that this - * Status response refers to. - * - * @var integer - */ - var $_cmdRef; - - /** - * The command (Add, Replace, etc) sent to the client, that this Status - * response refers to. - * - * @var string - */ - var $_cmd; - - /** - * The server ID of the sent object, that this Status response refers to. - * - * This element is optional. If specified, Status response refers to a - * single Item in the command sent to the client. It refers to all Items in - * the sent command otherwise. - * - * @var string - */ - var $_sourceRef; - - - /** - * The client ID of the sent object, that this Status response refers to. - * - * This element is optional. If specified, Status response refers to a - * single Item in the command sent to the client. It refers to all Items in - * the sent command otherwise. - * - * @var string - */ - var $_targetRef; - - var $_chalMetaFormat; - - var $_chalMetaType; - - var $_chalMetaNextNonce; - - var $_itemDataAnchorNext; - - var $_itemDataAnchorLast; - - var $_itemTargetLocURI; - - var $_itemSourceLocURI; - - var $_syncItems; - - /** - * Constructor. - * - * @param integer $response The response code. - * @param string $cmd The command sent to the client, - * that this Status response refers to. - */ - function Horde_SyncML_Command_Status($response = null, $cmd = null) - { - if ($response != null) { - $this->_response = $response; - } - - if ($cmd != null) { - $this->_cmd = $cmd; - } - } - - function output($currentCmdID, &$output) - { - $state = &$_SESSION['SyncML.state']; - - $attrs = array(); - - if ($this->_cmd != null) { - $output->startElement($state->getURI(), 'Status', $attrs); - - $output->startElement($state->getURI(), 'CmdID', $attrs); - $chars = $currentCmdID; - $output->characters($chars); - $output->endElement($state->getURI(), 'CmdID'); - - $output->startElement($state->getURI(), 'MsgRef', $attrs); - $chars = $state->getMsgID(); - $output->characters($chars); - $output->endElement($state->getURI(), 'MsgRef'); - - $output->startElement($state->getURI(), 'CmdRef', $attrs); - $chars = $this->_cmdRef; - $output->characters($chars); - $output->endElement($state->getURI(), 'CmdRef'); - - $output->startElement($state->getURI(), 'Cmd', $attrs); - $chars = $this->_cmd; - $output->characters($chars); - $output->endElement($state->getURI(), 'Cmd'); - - if (isset($this->_targetRef)) { - $output->startElement($state->getURI(), 'TargetRef', $attrs); - $chars = $this->_targetRef; - $output->characters($chars); - $output->endElement($state->getURI(), 'TargetRef'); - } - - if (isset($this->_sourceRef)) { - $output->startElement($state->getURI(), 'SourceRef', $attrs); - $chars = $this->_sourceRef; - $output->characters($chars); - $output->endElement($state->getURI(), 'SourceRef'); - } - - // If we are responding to the SyncHdr and we are not - // authorized then request basic authorization. - // - // FIXME: Right now we always send this, ignoring the - // isAuthorized() test. Is that correct? - if ($this->_cmd == 'SyncHdr' && !$state->isAuthorized()) { - $this->_chalMetaFormat = 'b64'; - $this->_chalMetaType = 'syncml:auth-basic'; - } - - if (isset($this->_chalMetaFormat) && isset($this->_chalMetaType)) { - $output->startElement($state->getURI(), 'Chal', $attrs); - $output->startElement($state->getURI(), 'Meta', $attrs); - - $metainfuri = $state->getURIMeta(); - - $output->startElement($metainfuri, 'Format', $attrs); - $chars = $this->_chalMetaFormat; - $output->characters($chars); - $output->endElement($metainfuri, 'Format'); - - $output->startElement($metainfuri, 'Type', $attrs); - $chars = $this->_chalMetaType; - $output->characters($chars); - $output->endElement($metainfuri, 'Type'); - - // $output->startElement($metainfuri, 'NextNonce', $attrs); - // $chars = $this->_chalMetaNextNonce; - // $output->characters($chars); - // $output->endElement($metainfuri, 'NextNonce'); - - $output->endElement($state->getURI(), 'Meta'); - $output->endElement($state->getURI(), 'Chal'); - } - - $output->startElement($state->getURI(), 'Data', $attrs); - $chars = $this->_response; - $output->characters($chars); - $output->endElement($state->getURI(), 'Data'); - - if (isset($this->_itemDataAnchorNext) || isset($this->_itemDataAnchorLast)) { - $output->startElement($state->getURI(), 'Item', $attrs); - $output->startElement($state->getURI(), 'Data', $attrs); - - $metainfuri = $state->getURIMeta(); - // $metainfuri = $state->getURI(); // debug by FOU - - $output->startElement($metainfuri, 'Anchor', $attrs); - - if (isset($this->_itemDataAnchorNext)) { - - $output->startElement($metainfuri, 'Next', $attrs); - $chars = $this->_itemDataAnchorNext; - $output->characters($chars); - $output->endElement($metainfuri, 'Next'); - } - - if (isset($this->_itemDataAnchorLast)) { - - $output->startElement($metainfuri, 'Last', $attrs); - $chars = $this->_itemDataAnchorLast; - $output->characters($chars); - $output->endElement($metainfuri, 'Last'); - } - - $output->endElement($metainfuri, 'Anchor'); - - $output->endElement($state->getURI(), 'Data'); - $output->endElement($state->getURI(), 'Item'); - } - - if (isset($this->_syncItems)) { - // Support multible items per command - foreach ($this->_syncItems as $locURI => &$syncItem) { - $output->startElement($state->getURI(), 'Item', $attrs); - $output->startElement($state->getURI(), 'Source', $attrs); - $output->startElement($state->getURI(), 'LocURI', $attrs); - $output->characters($locURI); - $output->endElement($state->getURI(), 'LocURI'); - $output->endElement($state->getURI(), 'Source'); - $output->endElement($state->getURI(), 'Item'); - } - } elseif (isset($this->_itemTargetLocURI) || isset($this->_itemSourceLocURI)) { - $output->startElement($state->getURI(), 'Item', $attrs); - - if (isset($this->_itemTargetLocURI)) { - $output->startElement($state->getURI(), 'Target', $attrs); - $output->startElement($state->getURI(), 'LocURI', $attrs); - $output->characters($this->_itemTargetLocURI); - $output->endElement($state->getURI(), 'LocURI'); - $output->endElement($state->getURI(), 'Target'); - } - if (isset($this->_itemSourceLocURI)) { - $output->startElement($state->getURI(), 'Source', $attrs); - $output->startElement($state->getURI(), 'LocURI', $attrs); - $output->characters($this->_itemSourceLocURI); - $output->endElement($state->getURI(), 'LocURI'); - $output->endElement($state->getURI(), 'Source'); - } - $output->endElement($state->getURI(), 'Item'); - } - - $output->endElement($state->getURI(), 'Status'); - - $currentCmdID++; - - } - - return $currentCmdID; - } - - /** - * Setter for property response. - * - * @param string $response New value of property response. - */ - function setResponse($response) - { - $this->_response = $response; - } - - /** - * Setter for property cmd. - * - * @param string $cmd New value of property cmd. - */ - function setCmd($cmd) - { - $this->_cmd = $cmd; - } - - /** - * Setter for property cmdRef. - * - * @param string $cmdRef New value of property cmdRef. - */ - function setCmdRef($cmdRef) - { - $this->_cmdRef = $cmdRef; - } - - /** - * Setter for property sourceRef. - * - * @param string $sourceRef New value of property sourceRef. - */ - function setSourceRef($sourceRef) - { - $this->_sourceRef = $sourceRef; - } - - /** - * Setter for property targetRef. - * - * @param string $targetRef New value of property targetRef. - */ - function setTargetRef($targetRef) - { - $this->_targetRef = $targetRef; - } - - /** - * Setter for property itemDataAnchorNext. - * - * @param string $itemDataAnchorNext New value of property itemDataAnchorNext. - */ - function setItemDataAnchorNext($itemDataAnchorNext) - { - $this->_itemDataAnchorNext = $itemDataAnchorNext; - } - - /** - * Setter for property itemDataAnchorLast. - * - * @param string $itemDataAnchorLast New value of property itemDataAnchorLast. - */ - function setItemDataAnchorLast($itemDataAnchorLast) - { - $this->_itemDataAnchorLast = $itemDataAnchorLast; - } - - /** - * Setter for property itemSourceLocURI. - * - * @param string $itemSourceLocURI New value of property itemSourceLocURI. - */ - function setItemSourceLocURI($itemSourceLocURI) - { - $this->_itemSourceLocURI = $itemSourceLocURI; - } - - /** - * Setter for property itemTargetLocURI. - * - * @param string $itemTargetLocURI New value of property itemTargetLocURI. - */ - function setItemTargetLocURI($itemTargetLocURI) - { - $this->_itemTargetLocURI = $itemTargetLocURI; - } - - /** - * Setter for the the list of handled SyncItems - * - * @param array $syncItems The Items of the command - */ - function setSyncItems(&$syncItems) - { - $this->_syncItems = $syncItems; - } -} diff --git a/phpgwapi/inc/horde/Horde/SyncML/Command/Sync.php b/phpgwapi/inc/horde/Horde/SyncML/Command/Sync.php deleted file mode 100644 index d65944a47b..0000000000 --- a/phpgwapi/inc/horde/Horde/SyncML/Command/Sync.php +++ /dev/null @@ -1,267 +0,0 @@ - - * @author Joerg Lehrke - * @copyright (c) The Horde Project (http://www.horde.org/) - * @version $Id$ - */ -include_once 'Horde/SyncML/State.php'; -include_once 'Horde/SyncML/Command.php'; -include_once 'Horde/SyncML/Command/Sync/SyncElement.php'; -include_once 'Horde/SyncML/Sync/TwoWaySync.php'; -include_once 'Horde/SyncML/Sync/SlowSync.php'; -include_once 'Horde/SyncML/Sync/OneWayFromServerSync.php'; -include_once 'Horde/SyncML/Sync/OneWayFromClientSync.php'; -include_once 'Horde/SyncML/Sync/RefreshFromServerSync.php'; -include_once 'Horde/SyncML/Sync/RefreshFromClientSync.php'; - -class Horde_SyncML_Command_Sync extends Horde_SyncML_Command { - - /** - * Name of the command. - * - * @var string - */ - var $_cmdName = 'Sync'; - - /** - * Source database of the command. - * - * @var string - */ - var $_sourceURI; - - /** - * Target database of the command. - * - * @var string - */ - var $_targetURI; - - /** - * Optional parameter for the Target. - * - * @var string - */ - var $_targetURIParameters; - - /** - * SyncML_SyncElement object for the currently parsed sync command. - * - * @var SyncML_SyncElement - */ - var $_curItem; - - /** - * List of all SyncML_SyncElement objects that have parsed. - * - * @var array - */ - var $_syncElements = array(); - - function output($currentCmdID, &$output) - { - $state = &$_SESSION['SyncML.state']; - - Horde::logMessage('SyncML: $this->_targetURI = ' . $this->_targetURI, __FILE__, __LINE__, PEAR_LOG_DEBUG); - - $status = new Horde_SyncML_Command_Status(RESPONSE_OK, 'Sync'); - - $status->setCmdRef($this->_cmdID); - - if ($this->_targetURI != null) { - $status->setTargetRef((isset($this->_targetURIParameters) ? $this->_targetURI.'?/'.$this->_targetURIParameters : $this->_targetURI)); - } - - if ($this->_sourceURI != null) { - $status->setSourceRef($this->_sourceURI); - } - - $currentCmdID = $status->output($currentCmdID, $output); - - if (($sync = &$state->getSync($this->_targetURI))) { - $currentCmdID = $sync->startSync($currentCmdID, $output); - - foreach ($this->_syncElements as $element) { - $currentCmdID = $sync->nextSyncCommand($currentCmdID, $element, $output); - } - } - - return $currentCmdID; - } - - - function startElement($uri, $element, $attrs) - { - parent::startElement($uri, $element, $attrs); - - switch (count($this->_stack)) { - case 2: - if ($element == 'Replace' || - $element == 'Add' || - $element == 'Delete') { - Horde::logMessage("SyncML: sync element $element found", __FILE__, __LINE__, PEAR_LOG_DEBUG); - $this->_curItem = &Horde_SyncML_Command_Sync_SyncElement::factory($element); - } - break; - } - if (isset($this->_curItem)) { - $this->_curItem->startElement($uri, $element, $attrs); - } - } - - - // We create a seperate Sync Element for the Sync Data sent - // from the Server to the client as we want to process the - // client sync information before. - - function syncToClient($currentCmdID, &$output) - { - Horde::logMessage('SyncML: starting sync to client', - __FILE__, __LINE__, PEAR_LOG_DEBUG); - - $state = &$_SESSION['SyncML.state']; - - if ($state->getSyncStatus() >= CLIENT_SYNC_FINNISHED - && $state->getSyncStatus() < SERVER_SYNC_FINNISHED) - { - $deviceInfo = $state->getClientDeviceInfo(); - if (($targets = $state->getTargets())) { - foreach ($targets as $target) - { - $sync = &$state->getSync($target); - Horde::logMessage('SyncML[' . session_id() . ']: sync alerttype ' . - $sync->_syncType . ' found for target ' . $target, - __FILE__, __LINE__, PEAR_LOG_DEBUG); - if ($sync->_syncType == ALERT_ONE_WAY_FROM_CLIENT || - $sync->_syncType == ALERT_REFRESH_FROM_CLIENT) { - Horde::logMessage('SyncML[' . session_id() . - ']: From client Sync, no sync of ' . $target . - ' to client', __FILE__, __LINE__, PEAR_LOG_DEBUG); - $state->clearSync($target); - - } elseif ($state->getSyncStatus() >= CLIENT_SYNC_ACKNOWLEDGED) { - - Horde::logMessage("SyncML: starting sync to client $target", - __FILE__, __LINE__, PEAR_LOG_DEBUG); - $attrs = array(); - - $state->setSyncStatus(SERVER_SYNC_DATA_PENDING); - - $output->startElement($state->getURI(), 'Sync', $attrs); - $output->startElement($state->getURI(), 'CmdID', $attrs); - $output->characters($currentCmdID); - $currentCmdID++; - $output->endElement($state->getURI(), 'CmdID'); - - $output->startElement($state->getURI(), 'Target', $attrs); - $output->startElement($state->getURI(), 'LocURI', $attrs); - $chars = $sync->_sourceLocURI; - $output->characters($chars); - $output->endElement($state->getURI(), 'LocURI'); - $output->endElement($state->getURI(), 'Target'); - - $output->startElement($state->getURI(), 'Source', $attrs); - $output->startElement($state->getURI(), 'LocURI', $attrs); - $chars = (isset($sync->_targetLocURIParameters) ? $sync->_targetLocURI.'?/'.$sync->_targetLocURIParameters : $sync->_targetLocURI); - $output->characters($chars); - $output->endElement($state->getURI(), 'LocURI'); - $output->endElement($state->getURI(), 'Source'); - - if(!$sync->_syncDataLoaded) - { - $numberOfItems = $sync->loadData(); - if($deviceInfo['supportNumberOfChanges']) - { - $output->startElement($state->getURI(), 'NumberOfChanges', $attrs); - $output->characters($numberOfItems); - $output->endElement($state->getURI(), 'NumberOfChanges'); - } - } - - $currentCmdID = $sync->endSync($currentCmdID, $output); - - $output->endElement($state->getURI(), 'Sync'); - - if (isset($state->curSyncItem) || - $state->getNumberOfElements() === false) { - break; - } - } else { - Horde::logMessage("SyncML: Waiting for client ACKNOWLEDGE for $target", - __FILE__, __LINE__, PEAR_LOG_DEBUG); - } - } - } - - // no syncs left - if ($state->getTargets() === false && - !isset($state->curSyncItem)) { - $state->setSyncStatus(SERVER_SYNC_FINNISHED); - } - Horde::logMessage('SyncML: syncStatus(syncToClient) = ' . - $state->getSyncStatus(), __FILE__, __LINE__, PEAR_LOG_DEBUG); - } - return $currentCmdID; - } - - function endElement($uri, $element) - { - if (isset($this->_curItem)) { - $this->_curItem->endElement($uri, $element); - } - - switch (count($this->_stack)) { - case 2: - if ($element == 'Replace' || - $element == 'Add' || - $element == 'Delete') { - $this->_syncElements[] = &$this->_curItem; - unset($this->_curItem); - } - break; - - case 3: - if ($element == 'LocURI' && !isset($this->_curItem)) { - if ($this->_stack[1] == 'Source') { - $this->_sourceURI = trim($this->_chars); - } elseif ($this->_stack[1] == 'Target') { - $targetURIData = explode('?/',trim($this->_chars)); - - $this->_targetURI = $targetURIData[0]; - - if (isset($targetURIData[1])) { - $this->_targetURIParameters = $targetURIData[1]; - } - } - } - break; - } - - parent::endElement($uri, $element); - - } - - function characters($str) - { - if (isset($this->_curItem)) { - $this->_curItem->characters($str); - } else { - if (isset($this->_chars)) { - $this->_chars .= $str; - } else { - $this->_chars = $str; - } - } - } - -} diff --git a/phpgwapi/inc/horde/Horde/SyncML/Command/Sync/Add.php b/phpgwapi/inc/horde/Horde/SyncML/Command/Sync/Add.php deleted file mode 100644 index 0517faa76e..0000000000 --- a/phpgwapi/inc/horde/Horde/SyncML/Command/Sync/Add.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright (c) The Horde Project (http://www.horde.org/) - * @version $Id$ - */ -include_once 'Horde/SyncML/Command/Sync/SyncElement.php'; - -class Horde_SyncML_Command_Sync_Add extends Horde_SyncML_Command_Sync_SyncElement { - - var $_status = RESPONSE_ITEM_ADDED; - - function output($currentCmdID, &$output) - { - $status = new Horde_SyncML_Command_Status($this->_status, 'Add'); - $status->setCmdRef($this->_cmdID); - - if (!empty($this->_items)) { - $status->setSyncItems($this->_items); - } - - return $status->output($currentCmdID, $output); - } - -} diff --git a/phpgwapi/inc/horde/Horde/SyncML/Command/Sync/ContentSyncElement.php b/phpgwapi/inc/horde/Horde/SyncML/Command/Sync/ContentSyncElement.php deleted file mode 100644 index f760a96616..0000000000 --- a/phpgwapi/inc/horde/Horde/SyncML/Command/Sync/ContentSyncElement.php +++ /dev/null @@ -1,164 +0,0 @@ - - * @author Joerg Lehrke - * @copyright (c) The Horde Project (http://www.horde.org/) - * @version $Id$ - */ -include_once 'Horde/SyncML/State.php'; -include_once 'Horde/SyncML/Command/Sync/SyncElementItem.php'; - -class Horde_SyncML_Command_Sync_ContentSyncElement extends Horde_SyncML_Command_Sync_SyncElementItem { - - function outputCommand($currentCmdID, &$output, $command) - { - $state = $_SESSION['SyncML.state']; - $maxMsgSize = $state->getMaxMsgSizeClient(); - $maxGUIDSize = $state->getMaxGUIDSizeClient(); - - if ($this->_moreData) { - $command = $this->_command; - } else { - $this->_command = $command; - } - - $attrs = array(); - $contentFormat = isset($this->_contentFormat) ? strtolower($this->_contentFormat) : ''; - $output->startElement($state->getURI(), $command, $attrs); - - $output->startElement($state->getURI(), 'CmdID', $attrs); - $output->characters($currentCmdID); - $output->endElement($state->getURI(), 'CmdID'); - - if (isset($this->_content) && !$this->_moreData) { - $this->_contentSize = strlen($this->_content); - } else { - $this->_contentSize = 0; - } - switch ($contentFormat) { - case 'strictxml': - break; - case 'htmlenc': - if (!$state->isWBXML() && $this->_contentSize) { - $this->_content = htmlspecialchars($this->_content, ENT_COMPAT, 'UTF-8'); - } - break; - case 'b64': - if ($this->_contentSize) { - $this->_content = base64_encode($this->_content); - } - default: - $contentFormat = ''; - } - - // - if ($this->_contentSize || isset($this->_contentType) || - (!$contentFormat && isset($this->_contentFormat))) { - $output->startElement($state->getURI(), 'Meta', $attrs); - if (isset($this->_contentType)) { - $output->startElement($state->getURIMeta(), 'Type', $attrs); - $output->characters($this->_contentType); - $output->endElement($state->getURIMeta(), 'Type'); - } - if (!$contentFormat && isset($this->_contentFormat)) { - $output->startElement($state->getURIMeta(), 'Format', $attrs); - $output->characters($this->_contentFormat); - $output->endElement($state->getURIMeta(), 'Format'); - } - if ($this->_contentSize) { - $output->startElement($state->getURIMeta(), 'Size', $attrs); - $output->characters(($this->_contentSize)); - $output->endElement($state->getURIMeta(), 'Size'); - } - $output->endElement($state->getURI(), 'Meta'); - } - - if (isset($this->_content) || isset($this->_luid) || isset($this->_guid)) { - $output->startElement($state->getURI(), 'Item', $attrs); - - // - if (isset($this->_guid)) { - $output->startElement($state->getURI(), 'Source', $attrs); - $output->startElement($state->getURI(), 'LocURI', $attrs); - $chars = substr($this->_guid, 0, $maxGUIDSize); - $state->setUIDMapping($this->_guid, $chars); - $output->characters($chars); - $output->endElement($state->getURI(), 'LocURI'); - $output->endElement($state->getURI(), 'Source'); - } - - // - if (isset($this->_luid)) { - $output->startElement($state->getURI(), 'Target', $attrs); - $output->startElement($state->getURI(), 'LocURI', $attrs); - $output->characters($this->_luid); - $output->endElement($state->getURI(), 'LocURI'); - $output->endElement($state->getURI(), 'Target'); - } - - - // - if (isset($this->_content)) { - $this->_contentSize = strlen($this->_content); - $output->startElement($state->getURI(), 'Data', $attrs); - $currentSize = $output->getOutputSize(); - Horde::logMessage("SyncML: $command: current = $currentSize, max = $maxMsgSize", __FILE__, __LINE__, PEAR_LOG_DEBUG); - if (!$maxMsgSize || - (($currentSize + MIN_MSG_LEFT + $this->_contentSize + 12) <= $maxMsgSize)) { - $chars = $this->_content; - unset($this->_content); - $this->_moreData = false; - } else { - $sizeLeft = $maxMsgSize - $currentSize - MIN_MSG_LEFT - 12; - if ($sizeLeft < 0) { - Horde::logMessage("SyncML: $command: split with $currentSize for $maxMsgSize, increase MIN_MSG_LEFT!", __FILE__, __LINE__, PEAR_LOG_WARNING); - $sizeLeft = 0; - } - // don't let us loose characters by trimming - while (($this->_contentSize > $sizeLeft) && - (strlen(trim(substr($this->_content, $sizeLeft - 1, 2))) < 2)) { - Horde::logMessage("SyncML: $command: split at $sizeLeft hit WS!", __FILE__, __LINE__, PEAR_LOG_DEBUG); - $sizeLeft++; - } - $chars = substr($this->_content, 0, $sizeLeft); - $this->_content = substr($this->_content, $sizeLeft, $this->_contentSize - $sizeLeft); - Horde::logMessage("SyncML: $command: " - . $this->_contentSize . " split at $sizeLeft:\n" - . $chars, __FILE__, __LINE__, PEAR_LOG_DEBUG); - $this->_moreData = true; - } - switch ($contentFormat) { - case 'strictxml': - if (!$state->isWBXML()) { - $chars = ''; - } - break; - } - $output->characters($chars); - $output->endElement($state->getURI(), 'Data'); - - // - if ($this->_moreData) { - $output->startElement($state->getURI(), 'MoreData', $attrs); - $output->endElement($state->getURI(), 'MoreData'); - } - } - $output->endElement($state->getURI(), 'Item'); - } - - $output->endElement($state->getURI(), $command); - - $currentCmdID++; - - return $currentCmdID; - } -} diff --git a/phpgwapi/inc/horde/Horde/SyncML/Command/Sync/Delete.php b/phpgwapi/inc/horde/Horde/SyncML/Command/Sync/Delete.php deleted file mode 100644 index b64bde926a..0000000000 --- a/phpgwapi/inc/horde/Horde/SyncML/Command/Sync/Delete.php +++ /dev/null @@ -1,32 +0,0 @@ - - * @copyright (c) The Horde Project (http://www.horde.org/) - * @version $Id$ - */ -include_once 'Horde/SyncML/Command/Sync/SyncElement.php'; - -class Horde_SyncML_Command_Sync_Delete extends Horde_SyncML_Command_Sync_SyncElement { - - function output($currentCmdID, &$output) - { - $status = new Horde_SyncML_Command_Status($this->_status, 'Delete'); - $status->setCmdRef($this->_cmdID); - - if (!empty($this->_items)) { - $status->setSyncItems($this->_items); - } - - return $status->output($currentCmdID, $output); - } - -} diff --git a/phpgwapi/inc/horde/Horde/SyncML/Command/Sync/Replace.php b/phpgwapi/inc/horde/Horde/SyncML/Command/Sync/Replace.php deleted file mode 100644 index 3e30982a7a..0000000000 --- a/phpgwapi/inc/horde/Horde/SyncML/Command/Sync/Replace.php +++ /dev/null @@ -1,31 +0,0 @@ - - * @copyright (c) The Horde Project (http://www.horde.org/) - * @version $Id$ - */ -include_once 'Horde/SyncML/Command/Sync/SyncElement.php'; - -class Horde_SyncML_Command_Sync_Replace extends Horde_SyncML_Command_Sync_SyncElement { - - function output($currentCmdID, &$output) { - $status = new Horde_SyncML_Command_Status($this->_status, 'Replace'); - $status->setCmdRef($this->_cmdID); - - if (!empty($this->_items)) { - $status->setSyncItems($this->_items); - } - - return $status->output($currentCmdID, $output); - } - -} diff --git a/phpgwapi/inc/horde/Horde/SyncML/Command/Sync/SyncElement.php b/phpgwapi/inc/horde/Horde/SyncML/Command/Sync/SyncElement.php deleted file mode 100644 index 6eb923714c..0000000000 --- a/phpgwapi/inc/horde/Horde/SyncML/Command/Sync/SyncElement.php +++ /dev/null @@ -1,232 +0,0 @@ - - * @author Joerg Lehrke - * @copyright (c) The Horde Project (http://www.horde.org/) - * @version $Id$ - */ -include_once 'Horde/SyncML/Command.php'; - -class Horde_SyncML_Command_Sync_SyncElement extends Horde_SyncML_Command { - - var $_luid; - var $_guid; - var $_contentSize = 0; - var $_contentType; - var $_contentFormat; - var $_status = RESPONSE_OK; - var $_curItem; - var $_items = array(); - var $_failed = array(); - var $_moreData = false; - var $_command = false; - - function &factory($command, $params = null) { - include_once 'Horde/SyncML/Command/Sync/SyncElementItem.php'; - @include_once 'Horde/SyncML/Command/Sync/' . $command . '.php'; - - $class = 'Horde_SyncML_Command_Sync_' . $command; - - if (class_exists($class)) { - #Horde::logMessage('SyncML: Class definition of ' . $class . ' found in SyncElement::factory.', __FILE__, __LINE__, PEAR_LOG_DEBUG); - return $element = new $class($params); - } else { - Horde::logMessage('SyncML: Class definition of ' . $class . ' not found in SyncElement::factory.', __FILE__, __LINE__, PEAR_LOG_DEBUG); - require_once 'PEAR.php'; - return PEAR::raiseError('Class definition of ' . $class . ' not found.'); - } - } - - function startElement($uri, $element, $attrs) { - parent::startElement($uri, $element, $attrs); - $state = &$_SESSION['SyncML.state']; - - switch (count($this->_stack)) { - case 1: - $this->_command = $element; - break; - case 2: - if ($element == 'Item') { - if (isset($state->curSyncItem)) { - // Copy from state in case of . - $this->_curItem = &$state->curSyncItem; - if (isset($this->_luid) && - ($this->_luid != $this->_curItem->_luid)) { - Horde::logMessage('SyncML: moreData mismatch for LocURI ' . - $this->_curItem->_luid . ' (' . $this->_luid . ')', __FILE__, __LINE__, PEAR_LOG_ERROR); - } else { - Horde::logMessage('SyncML: moreData item found for LocURI ' . $this->_curItem->_luid, __FILE__, __LINE__, PEAR_LOG_DEBUG); - } - unset($state->curSyncItem); - } else { - $this->_curItem = new Horde_SyncML_Command_Sync_SyncElementItem(); - } - $this->_moreData = false; - } - break; - } - } - - function endElement($uri, $element) { - $state = &$_SESSION['SyncML.state']; - $search = array('/ *\n/','/ *$/m'); - $replace = array('',''); - - switch (count($this->_stack)) { - case 1: - $this->_command = false; - // Need to add sync elements to the Sync method? - #error_log('total # of items: '.count($this->_items)); - #error_log(print_r($this->_items[10], true)); - break; - case 2; - if($element == 'Item') { - if ($this->_luid) { - $this->_curItem->setLocURI($this->_luid); - $this->_curItem->setContentType($this->_contentType); - $this->_curItem->setContentFormat($this->_contentFormat); - $this->_curItem->setCommand($this->_command); - - if ($this->_contentSize) - $this->_curItem->setContentSize($this->_contentSize); - if ($this->_moreData) { - $state->curSyncItem = &$this->_curItem; - Horde::logMessage('SyncML: moreData item saved for LocURI ' . $this->_curItem->_luid, __FILE__, __LINE__, PEAR_LOG_DEBUG); - } else { - $content = $this->_curItem->getContent(); - $contentSize = strlen($content); - if ((($size = $this->_curItem->getContentSize()) !== false) && - abs($contentSize - $size) > 3) { - Horde::logMessage('SyncML: content size mismatch for LocURI ' . $this->_luid . - ": $contentSize ($size) : " . $content, - __FILE__, __LINE__, PEAR_LOG_WARNING); - $this->_failed[$this->_luid] = $this->_curItem; - } else { - if (strtolower($this->_curItem->getContentFormat()) == 'b64') { - $content = ($content ? base64_decode($content) : ''); - $this->_curItem->setContent($content); - #Horde::logMessage('SyncML: BASE64 encoded item for LocURI ' - # . $this->_curItem->_luid . ":\n $content", __FILE__, __LINE__, PEAR_LOG_DEBUG); - } - #Horde::logMessage('SyncML: Data for ' . $this->_luid . ': ' . $this->_curItem->getContent(), __FILE__, __LINE__, PEAR_LOG_DEBUG); - $this->_items[$this->_luid] = $this->_curItem; - } - } - } - unset($this->_contentSize); - unset($this->_luid); - } - break; - case 3: - switch ($element) { - case 'Data': - $content = $this->_chars; - if ($this->_contentFormat == 'b64') $content = trim($content); - #Horde::logMessage('SyncML: Data for ' . $this->_luid . ': ' . $content, __FILE__, __LINE__, PEAR_LOG_DEBUG); - $this->_curItem->_content .= $content; - break; - case 'MoreData': - $this->_moreData = true; - break; - case 'Type': - if (empty($this->_contentType)) { - $this->_contentType = trim($this->_chars); - } - break; - case 'Format': - $this->_contentFormat = strtolower(trim($this->_chars)); - break; - case 'Size': - $this->_contentSize = trim($this->_chars); - break; - } - break; - - case 4: - switch ($element) { - case 'LocURI': - if ($this->_stack[2] == 'Source') { - $this->_luid = trim($this->_chars); - } - break; - case 'Type': - $this->_contentType = trim($this->_chars); - break; - case 'Format': - $this->_contentFormat = strtolower(trim($this->_chars)); - break; - case 'Size': - $this->_contentSize = trim($this->_chars); - break; - } - break; - } - - parent::endElement($uri, $element); - } - - function getSyncElementItems() { - return (array)$this->_items; - } - - function getSyncElementFailures() { - return (array)$this->_failed; - } - - function getLocURI() - { - return $this->_luid; - } - - function getGUID() - { - return $this->_guid; - } - - function setLocURI($luid) - { - $this->_luid = $luid; - } - - function setGUID($guid) - { - $this->_guid = $guid; - } - - function setContentType($c) - { - $this->_contentType = $c; - } - - function getContentType() - { - return $this->_contentType; - } - - function getContent() - { - if ($this->_curItem) { - return $this->_curItem->getcontent(); - } - return false; - } - - function hasMoreData() - { - return $this->_moreData; - } - - function setStatus($_status) - { - $this->_status = $_status; - } -} diff --git a/phpgwapi/inc/horde/Horde/SyncML/Command/Sync/SyncElementItem.php b/phpgwapi/inc/horde/Horde/SyncML/Command/Sync/SyncElementItem.php deleted file mode 100644 index 6ef74146bb..0000000000 --- a/phpgwapi/inc/horde/Horde/SyncML/Command/Sync/SyncElementItem.php +++ /dev/null @@ -1,95 +0,0 @@ - - * @copyright (c) The Horde Project (http://www.horde.org/) - * @version $Id$ - */ -include_once 'Horde/SyncML/Command.php'; - -class Horde_SyncML_Command_Sync_SyncElementItem { - - var $_luid; - var $_guid; - var $_content = ''; - var $_contentSize; - var $_contentType; - var $_contentFormat; - var $_command; - var $_moreData = false; - - function getLocURI() { - return $this->_luid; - } - - function getGUID() { - return $this->_guid; - } - - function getContentType() { - return $this->_contentType; - } - - function getContentFormat() { - return $this->_contentFormat; - } - - function getContent() { - return $this->_content; - } - - function getContentSize() { - if (isset($this->_contentSize)) { - return $this->_contentSize; - } - return false; - } - - function getCommand() { - return $this->_command; - } - - function setLocURI($luid) { - $this->_luid = $luid; - } - - function setGUID($guid) { - $this->_guid = $guid; - } - - function setContent($_content) { - $this->_content = $_content; - } - - function setContentSize($_size) { - $this->_contentSize = $_size; - } - - function setContentType($_type) { - $this->_contentType = $_type; - } - - function setContentFormat($_format) { - $this->_contentFormat = $_format; - } - - function setMoreData($_status) { - $this->_moreData = $_status; - } - - function hasMoreData() { - return $this->_moreData; - } - - function setCommand($_command) { - $this->_command = $_command; - } -} diff --git a/phpgwapi/inc/horde/Horde/SyncML/State.php b/phpgwapi/inc/horde/Horde/SyncML/State.php deleted file mode 100644 index e065bf36ad..0000000000 --- a/phpgwapi/inc/horde/Horde/SyncML/State.php +++ /dev/null @@ -1,1316 +0,0 @@ - - * @copyright (c) The Horde Project (http://www.horde.org/) - * @version $Id$ - */ - -define('ALERT_DISPLAY', 100); - -// Not implemented. -define('ALERT_TWO_WAY', 200); -define('ALERT_SLOW_SYNC', 201); -define('ALERT_ONE_WAY_FROM_CLIENT', 202); -define('ALERT_REFRESH_FROM_CLIENT', 203); -define('ALERT_ONE_WAY_FROM_SERVER', 204); -define('ALERT_REFRESH_FROM_SERVER', 205); - -// Not implemented. -define('ALERT_TWO_WAY_BY_SERVER', 206); -define('ALERT_ONE_WAY_FROM_CLIENT_BY_SERVER', 207); -define('ALERT_REFRESH_FROM_CLIENT_BY_SERVER', 208); -define('ALERT_ONE_WAY_FROM_SERVER_BY_SERVER', 209); -define('ALERT_REFRESH_FROM_SERVER_BY_SERVER', 210); - -define('ALERT_RESULT_ALERT', 221); -define('ALERT_NEXT_MESSAGE', 222); -define('ALERT_NO_END_OF_DATA', 223); - -// Not (really) implemented. -define('ALERT_SUSPEND', 224); // New in SyncML 1.2 -define('ALERT_RESUME', 225); // New in SyncML 1.2 - -define('MIME_SYNCML_XML', 'application/vnd.syncml+xml'); -define('MIME_SYNCML_WBXML', 'application/vnd.syncml+wbxml'); - -define('MIME_SYNCML_DEVICE_INFO_XML', 'application/vnd.syncml-devinf+xml'); -define('MIME_SYNCML_DEVICE_INFO_WBXML', 'application/vnd.syncml-devinf+wbxml'); - -define('MIME_TEXT_PLAIN', 'text/plain'); -define('MIME_VCARD_V21', 'text/x-vcard'); -define('MIME_VCARD_V30', 'text/vcard'); - -define('MIME_VCALENDAR', 'text/x-vcalendar'); -define('MIME_ICALENDAR', 'text/calendar'); -define('MIME_XML_ICALENDAR', 'application/vnd.syncml-xcal'); - -define('MIME_MESSAGE', 'text/message'); - -define('MIME_SYNCML_XML_EMAIL', 'application/vnd.syncml-xmsg'); -define('MIME_SYNCML_XML_BOOKMARK', 'application/vnd.syncml-xbookmark'); -define('MIME_SYNCML_RELATIONAL_OBJECT', 'application/vnd.syncml-xrelational'); - -define('RESPONSE_IN_PROGRESS', 101); - -define('RESPONSE_OK', 200); -define('RESPONSE_ITEM_ADDED', 201); -define('RESPONSE_ACCEPTED_FOR_PROCESSING', 202); -define('RESPONSE_NONAUTHORIATATIVE_RESPONSE', 203); -define('RESPONSE_NO_CONTENT', 204); -define('RESPONSE_RESET_CONTENT', 205); -define('RESPONSE_PARTIAL_CONTENT', 206); -define('RESPONSE_CONFLICT_RESOLVED_WITH_MERGE', 207); -define('RESPONSE_CONFLICT_RESOLVED_WITH_CLIENT_WINS', 208); -define('RESPONSE_CONFILCT_RESOLVED_WITH_DUPLICATE', 209); -define('RESPONSE_DELETE_WITHOUT_ARCHIVE', 210); -define('RESPONSE_ITEM_NO_DELETED', 211); -define('RESPONSE_AUTHENTICATION_ACCEPTED', 212); -define('RESPONSE_CHUNKED_ITEM_ACCEPTED_AND_BUFFERED', 213); -define('RESPONSE_OPERATION_CANCELLED', 214); -define('RESPONSE_NO_EXECUTED', 215); -define('RESPONSE_ATOMIC_ROLL_BACK_OK', 216); - -define('RESPONSE_MULTIPLE_CHOICES', 300); -define('RESPONSE_MOVED_PERMANENTLY', 301); -define('RESPONSE_FOUND', 302); -define('RESPONSE_SEE_OTHER', 303); -define('RESPONSE_NOT_MODIFIED', 304); -define('RESPONSE_USE_PROXY', 305); - -define('RESPONSE_BAD_REQUEST', 400); -define('RESPONSE_INVALID_CREDENTIALS', 401); -define('RESPONSE_PAYMENT_NEEDED', 402); -define('RESPONSE_FORBIDDEN', 403); -define('RESPONSE_NOT_FOUND', 404); -define('RESPONSE_COMMAND_DENIED', 405); -define('RESPONSE_FEATURE_NOT_SUPPORTED', 406); -define('RESPONSE_MISSING_CREDENTIALS', 407); -define('RESPONSE_REQUEST_TIMEOUT', 408); -define('RESPONSE_CONFLICT_DETECTED', 409); -define('RESPONSE_ITEM_GONE', 410); -define('RESPONSE_SIZE_REQUIRED', 411); -define('RESPONSE_INCOMPLETE_COMMAND', 412); -define('RESPONSE_ENTITY_TO_LARGE', 413); -define('RESPONSE_URI_TOO_LONG', 414); -define('RESPONSE_UNSUPPORTED_MEDIA_TYPE', 415); -define('RESPONSE_REQUEST_SIZE_TOO_BIG', 416); -define('RESPONSE_RETRY_LATER', 417); -define('RESPONSE_ALREADY_EXISITS', 418); -define('RESPONSE_CONFLICT_RESOLVED_WITH_SERVER_WINS', 419); -define('RESPONSE_DEVICE_FULL', 420); -define('RESPONSE_UNKNOWN_SEARCH_GRAMMAR', 421); -define('RESPONSE_BAD_CGI', 422); -define('RESPONSE_SOFT_DELETE_CONFICT', 423); -define('RESPONSE_SIZE_MISMATCH', 424); -define('RESPONSE_PERMISSION_DENIED', 425); -define('RESPONSE_PARTIAL_ITEM_NOT_ACCEPTED', 426); -define('RESPONSE_ITEM_NOT_EMPTY', 427); -define('RESPONSE_MOVE_FAILED', 428); - -define('RESPONSE_COMMAND_FAILED', 500); -define('RESPONSE_COMMAND_NOT_IMPLEMENTED', 501); -define('RESPONSE_BAD_GATEWAY', 502); -define('RESPONSE_SERVICE_UNAVAILABLE', 503); -define('RESPONSE_GATEWAY_TIMEOUT', 504); -define('RESPONSE_DTD_VERSION_NOT_SUPPORTED', 505); -define('RESPONSE_PROCESSING_ERROR', 506); -define('RESPONSE_ATOMIC_FAILED', 507); -define('RESPONSE_REFRESH_REQUIRED', 508); -// define('RESPONSE_FUTURE_USE', 509); -define('RESPONSE_DATASTORE_FAILURE', 510); -define('RESPONSE_SERVER_FAILURE', 511); -define('RESPONSE_SYNCHRONIZATION_FAILED', 512); -define('RESPONSE_PROTOCOL_VERSION_NOT_SUPPORTED', 513); -define('RESPONSE_OPERATION_CANCELLED', 514); -define('RESPONSE_COMMAND_FAILED', 515); -define('RESPONSE_ATOMIC_ROLL_BACK_FAILED', 516); -define('RESPONSE_ATOMIC_RESPONSE_TOO_LARGE', 517); - -define('NAME_SPACE_URI_SYNCML_1_0', 'syncml:syncml1.0'); -define('NAME_SPACE_URI_SYNCML_1_1', 'syncml:syncml1.1'); -define('NAME_SPACE_URI_SYNCML_1_2', 'syncml:syncml1.2'); -define('NAME_SPACE_URI_METINF_1_0', 'syncml:metinf1.0'); -define('NAME_SPACE_URI_METINF_1_1', 'syncml:metinf1.1'); -define('NAME_SPACE_URI_METINF_1_2', 'syncml:metinf1.2'); -define('NAME_SPACE_URI_DEVINF_1_0', 'syncml:devinf1.0'); -define('NAME_SPACE_URI_DEVINF_1_1', 'syncml:devinf1.1'); -define('NAME_SPACE_URI_DEVINF_1_2', 'syncml:devinf1.2'); - -define('CLIENT_SYNC_STARTED', 1); -define('CLIENT_SYNC_FINNISHED', 2); -define('CLIENT_SYNC_ACKNOWLEDGED', 3); -define('SERVER_SYNC_DATA_PENDING', 4); -define('SERVER_SYNC_FINNISHED', 5); -define('SERVER_SYNC_ACKNOWLEDGED', 6); - -// conflict management -define('CONFLICT_CLIENT_WINNING', 0); -define('CONFLICT_SERVER_WINNING', 1); -define('CONFLICT_MERGE_DATA', 2); -define('CONFLICT_RESOLVED_WITH_DUPLICATE', 3); -define('CONFLICT_CLIENT_CHANGES_IGNORED', 4); -define('CONFLICT_CLIENT_REFRESH_ENFORCED', 5); - -define('MAX_DATA', 19); -define('MAX_ENTRIES', 10); // default -define('MAX_GUID_SIZE', 64); -define('MIN_MSG_LEFT', 200); // Overhead - -/** - * The Horde_SyncML_State class provides a SyncML state object. - * - * $Horde: framework/SyncML/SyncML/State.php,v 1.15 2004/07/26 09:24:38 jan Exp $ - * - * Copyright 2003-2004 Anthony Mills - * - * 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 Anthony Mills - * @version $Revision$ - * @since Horde 3.0 - * @package Horde_SyncML - * @modified Joerg Lehrke 2009/01/20, support all syn types - */ -class Horde_SyncML_State { - - var $_sessionID; - - var $_verProto; - - var $_msgID; - - var $_maxMsgSize; - - var $_maxGUIDSize; - - var $_targetURI; - - var $_sourceURI; - - var $_version; - - var $_locName; - - var $_password; - - /* - * integer 0 authorization pending - * -1 authorization failed - * 1 session is authorized - */ - var $_isAuthorized; - - var $_AuthConfirmed; - - var $_uri; - - var $_uriMeta; - - var $_syncs = array(); - - var $_clientAnchorNext = array(); // written to db after successful sync - - var $_serverAnchorLast = array(); - - var $_serverAnchorNext = array(); // written to db after successful sync - - var $_clientDeviceInfo; - - // array list of changed items, which need to be synced to the client - var $_changedItems; - - // array list of deleted items, which need to be synced to the client - var $_deletedItems; - - // array list of added items, which need to be synced to the client - var $_addedItems; - - // array list of items, which need to be refreshed at the client - var $_conflictItems; - - // current session status - var $_syncStatus = 0; - - var $_log = array(); - - // stores if we received Alert 222 already - var $_receivedAlert222 = false; - - // stores if we already requested the deviceinfo - var $_devinfoRequested = false; - - /* - * store the mappings of egw uids to client uids - */ - var $_uidMappings = array(); - - /** - * Current sync element sent from client. - * - * Stored in state if one element is split into multiple message packets. - * - * @var SyncML_SyncElement - */ - var $curSyncItem; - - /** - * Number of sync elements sent to client within current message. - * - * @var _numberOfElements - */ - var $_numberOfElements; - - /** - * Creates a new instance of Horde_SyncML_State. - */ - function Horde_SyncML_State($sourceURI, $locName, $sessionID, $password = false) - { - $this->setSourceURI($sourceURI); - $this->setLocName($locName); - $this->setSessionID($sessionID); - if ($password) { - $this->setPassword($password); - } - - $this->_isAuthorized = 0; - $this->_isAuthConfirmed = false; - } - - /** - * store the sent global uid - */ - function setUIDMapping($_realEgwUid, $_sentEgwUid) { - $this->_uidMappings[$_sentEgwUid] = $_realEgwUid; - } - - /** - * retrieve the real egw uid for a given send uid - */ - function getUIDMapping($_sentEgwUid) { - if(strlen("$_sentEgwUid") && isset($this->_uidMappings[$_sentEgwUid])) { - return $this->_uidMappings[$_sentEgwUid]; - } - - return false; - } - - /** - * Returns the DataTree used as persistence layer for SyncML. The - * datatree var should not be a class member of State as State is - * stored as a session var. Resource handles (=db connections) - * cannot be stored in sessions. - * - * @return object DataTree The DataTree object. - */ - function &getDataTree() - { - $driver = $GLOBALS['conf']['datatree']['driver']; - $params = Horde::getDriverConfig('datatree', $driver); - $params = array_merge($params, array( 'group' => 'syncml' )); - - return DataTree::singleton($driver, $params); - } - - function getLocName() - { - if(isset($this->_locName)) - return $this->_locName; - else - return False; - } - - function getSourceURI() - { - return $this->_sourceURI; - } - - function getTargetURI() - { - return $this->_targetURI; - } - - function getVersion() - { - return $this->_version; - } - - function &getAddedItems($_type) - { - if(isset($this->_addedItems[$_type])) - { - return $this->_addedItems[$_type]; - } - - return false; - } - - function &getChangedItems($_type) - { - if(isset($this->_changedItems[$_type])) - { - return $this->_changedItems[$_type]; - } - - return false; - } - - function &getDeletedItems($_type) - { - if(isset($this->_deletedItems[$_type])) - { - return $this->_deletedItems[$_type]; - } - - return false; - } - - function &getConflictItems($_type) - { - if(isset($this->_conflictItems[$_type])) - { - return $this->_conflictItems[$_type]; - } - - return false; - } - - function getMoreDataPending() - { - return $this->_moreDataPending; - } - - function getMsgID() - { - return $this->_msgID; - } - - function getMaxMsgSizeClient() - { - if (isset($this->_maxMsgSize)) { - return $this->_maxMsgSize; - } - return false; - } - - function setWBXML($wbxml) - { - $this->_wbxml = $wbxml; - } - - function isWBXML() - { - return !empty($this->_wbxml); - } - - function &getSyncStatus() - { - return $this->_syncStatus; - } - - function setAddedItems($_type, $_addedItems) - { - $this->_addedItems[$_type] = $_addedItems; - } - - function mergeAddedItems($_type, $_addedItems) - { - if (is_array($this->_addedItems[$_type])) { - $this->_addedItems[$_type] = array_merge($this->_addedItems[$_type], $_addedItems); - } else { - $this->_addedItems[$_type] = $_addedItems; - } - } - - function pushAddedItem($_type, $_addedItem) - { - $this->_addedItems[$_type][] = $_addedItem; - } - - function setChangedItems($_type, $_changedItems) - { - $this->_changedItems[$_type] = $_changedItems; - } - - function mergeChangedItems($_type, $_changedItems) - { - if (is_array($this->_changedItems[$_type])) { - $this->_changedItems[$_type] = array_merge($this->_changedItems[$_type], $_changedItems); - } else { - $this->_changedItems[$_type] = $_changedItems; - } - } - - function pushChangedItem($_type, $_changedItem) - { - $this->_changedItems[$_type][] = $_changedItem; - } - - function setClientDeviceInfo($clientDeviceInfo) - { - $this->_clientDeviceInfo = $clientDeviceInfo; - unset($this->_clientDeviceInfo['persistent']); - } - - function setDeletedItems($_type, $_deletedItems) - { - $this->_deletedItems[$_type] = $_deletedItems; - } - - function addConflictItem($_type, $_conflict) - { - $this->_conflictItems[$_type][] = $_conflict; - } - - function clearConflictItems($_type) - { - $this->_conflictItems[$_type] = array(); - } - - /** - * Setter for property msgID. - * @param msgID New value of property msgID. - */ - function setMsgID($msgID) - { - $this->_msgID = $msgID; - } - - /** - * Setter for property maxMsgSize. - * @param size New value of property maxMsgSize. - */ - function setMaxMsgSize($size) - { - $this->_maxMsgSize = $size; - } - - /** - * Setter for property locName. - * @param locName New value of property locName. - */ - function setLocName($locName) - { - $this->_locName = $locName; - } - - /** - * Setter for property locName. - * @param locName New value of property locName. - */ - function setPassword($password) - { - $this->_password = $password; - } - - function setSourceURI($sourceURI) - { - $this->_sourceURI = $sourceURI; - } - - function setSyncStatus($_syncStatus) - { - #Horde::logMessage('SyncML: syncState set to ==> ' . $_syncStatus, __FILE__, __LINE__, PEAR_LOG_DEBUG); - $this->_syncStatus = $_syncStatus; - } - - function setTargetURI($targetURI) - { - $this->_targetURI = $targetURI; - } - - function setVersion($version) - { - $this->_version = $version; - - if ($version == 2) { - $this->_uri = NAME_SPACE_URI_SYNCML_1_2; - $this->_uriMeta = NAME_SPACE_URI_METINF_1_2; - $this->_uriDevInf = NAME_SPACE_URI_DEVINF_1_2; - } elseif ($version == 1) { - $this->_uri = NAME_SPACE_URI_SYNCML_1_1; - $this->_uriMeta = NAME_SPACE_URI_METINF_1_1; - $this->_uriDevInf = NAME_SPACE_URI_DEVINF_1_1; - } else { - $this->_uri = NAME_SPACE_URI_SYNCML_1_0; - $this->_uriMeta = NAME_SPACE_URI_METINF_1_0; - $this->_uriDevInf = NAME_SPACE_URI_DEVINF_1_0; - } - - } - - function setSessionID($sessionID) - { - $this->_sessionID = $sessionID; - } - - function isAuthorized() - { - if (!$this->_isAuthorized) { - - if(strstr($this->_locName,'@') === False) - { - $this->_locName .= '@'.$GLOBALS['egw_info']['server']['default_domain']; - } - - #Horde::logMessage('SyncML: Authenticate ' . $this->_locName . ' - ' . $this->_password, __FILE__, __LINE__, PEAR_LOG_DEBUG); - - if($GLOBALS['sessionid'] = $GLOBALS['egw']->session->create($this->_locName,$this->_password,'text','u')) - { - $this->_isAuthorized = 1; - #Horde::logMessage('SyncML_EGW: Authentication of ' . $this->_locName . '/' . $GLOBALS['sessionid'] . ' succeded' , __FILE__, __LINE__, PEAR_LOG_DEBUG); - } - else - { - $this->_isAuthorized = -1; - Horde::logMessage('SyncML: Authentication of ' . $this->_locName . ' failed' , __FILE__, __LINE__, PEAR_LOG_DEBUG); - } - } - else - { - // store sessionID in a variable, because ->verify maybe resets that value - $sessionID = session_id(); - if(!$GLOBALS['egw']->session->verify($sessionID, 'staticsyncmlkp3')) - Horde::logMessage('SyncML_EGW: egw session('.$sessionID. ') not verified ' , __FILE__, __LINE__, PEAR_LOG_DEBUG); - } - - return ($this->_isAuthorized > 0); - } - - function isAuthConfirmed() - { - return $this->_AuthConfirmed; - } - - function AuthConfirmed() - { - $this->_AuthConfirmed = true; - } - - function clearSync($target) - { - unset($this->_syncs[$target]); - } - - function setSync($target, $sync) - { - $this->_syncs[$target] = $sync; - } - - function getSync($target) - { - if (isset($this->_syncs[$target])) { - return $this->_syncs[$target]; - } else { - return false; - } - } - - function getTargets() - { - if(count($this->_syncs) < 1) - return false; - - foreach($this->_syncs as $target => $sync) - { - $targets[] = $target; - } - - // Make sure we keep the order - sort($targets); - - return $targets; - } - - function needDeviceInfo() - { - if ($this->_devinfoRequested || count($this->_syncs) < 1) return false; - - $sendGetRequest = false; - - foreach($this->_syncs as $sync) - { - if (($source = $sync->getSourceLocURI()) && - is_a($this->getPreferedContentTypeClient($source), 'PEAR_Error')) { - $sendGetRequest = true; - break; - } - } - - return $sendGetRequest; - } - - function deviceInfoRequested() - { - $this->_devinfoRequested = true; - } - - function getURI() - { - /* - * The non WBXML devices (notably P900 and Sync4j seem to get confused - * by a element. They require - * just . So don't use an ns for non wbxml devices. - */ - if ($this->isWBXML()) { - return $this->_uri; - } else { - return ''; - } - } - - function getURIMeta() - { - return $this->_uriMeta; - } - - function getURIDevInf() - { - return $this->_uriDevInf; - } - - - /** - * Converts a Horde GUID (like - * kronolith:0d1b415fc124d3427722e95f0e926b75) to a client ID as - * used by the sync client (like 12) returns false if no such id - * is stored yet. - * - * Remember that the datatree is really a tree disguised as a - * table. So to look up the guid above, getId first looks for an - * entry 'kronolith' and then for an entry - * 0d1b415fc124d3427722e95f0e926b75 with kronolith as parent. - */ - function getLocID($type, $guid) - { - $dt = &$this->getDataTree(); - $id = $dt->getId($this->_locName . $this->_sourceURI . $type . $guid); - if (is_a($id, 'PEAR_Error')) { - return false; - } - - $gid = $dt->getObjectById($id); - if (is_a($gid, 'PEAR_Error')) { - return false; - } - - return $gid->get('locid'); - } - - /** - * Puts a given client $locid and Horde server $guid pair into the - * map table to allow mapping between the client's and server's - * IDs. Actually there are two maps: from the localid to the guid - * and vice versa. The localid is converted to a key as follows: - * this->_locName . $this->_sourceURI . $type . $locid so you can - * have different syncs with different devices. If an entry - * already exists, it is overwritten. - * Expired entries can be deleted at the next session start. - */ - function setUID($type, $locid, $guid, $ts=0, $expired=0) - { - $dt = &$this->getDataTree(); - - // Set $locid. - $gid = new DataTreeObject($this->_locName . $this->_sourceURI . $type . $guid); - $gid->set('type', $type); - $gid->set('locid', $locid); - $gid->set('ts', $ts); - $gid->set('expired', $expired); - - $r = $dt->add($gid); - if (is_a($r, 'PEAR_Error')) { - // Object already exists: update instead. - $r = $dt->updateData($gid); - } - $this->dieOnError($r, __FILE__, __LINE__); - - // Set $globaluid - $lid = new DataTreeObject($this->_locName . $this->_sourceURI . $type . $locid); - $lid->set('globaluid', $guid); - $r = $dt->add($lid); - if (is_a($r, 'PEAR_Error')) { - // object already exists: update instead. - $r = $dt->updateData($lid); - } - $this->dieOnError($r, __FILE__, __LINE__); - } - - /** - * Retrieves the Horde server guid (like - * kronolith:0d1b415fc124d3427722e95f0e926b75) for a given client - * locid. Returns false if no such id is stored yet. - * - * Opposite of getLocId which returns the locid for a given guid. - */ - function getGlobalUID($type, $locid) - { - $this->dieOnError($type, __FILE__, __LINE__); - $this->dieOnError($locid, __FILE__, __LINE__); - $this->dieOnError($locid, __FILE__, __LINE__); - $this->dieOnError($this->_locName, __FILE__, __LINE__); - $this->dieOnError($this->_sourceURI, __FILE__, __LINE__); - - $dt = &$this->getDataTree(); - - $id = $dt->getId($this->_locName . $this->_sourceURI . $type . $locid); - if (is_a($id, 'PEAR_Error')) { - return false; - } - $lid = $dt->getObjectById($id); - if (is_a($lid, 'PEAR_Error')) { - return false; - } - - return $lid->get('globaluid'); - } - - /** - * Returns the timestamp (if set) of the last change to the - * obj:guid, that was caused by the client. This is stored to - * avoid mirroring these changes back to the client. - */ - function getChangeTS($type, $guid) - { - $dt = &$this->getDataTree(); - - $id = $dt->getId($this->_locName . $this->_sourceURI . $type . $guid); - if (is_a($id, 'PEAR_Error')) { - return false; - } - - $gid = $dt->getObjectById($id); - if (is_a($gid, 'PEAR_Error')) { - return false; - } - - return $gid->get('ts'); - } - - /** - * Removes the locid<->guid mapping for the given locid. Returns - * the guid that was removed or false if no mapping entry was - * found. - */ - function removeUID($type, $locid) - { - $dt = &$this->getDataTree(); - - $id = $dt->getId($this->_locName . $this->_sourceURI . $type . $locid); - if (is_a($id, 'PEAR_Error')) { - Horde::logMessage("SyncML: state->removeUID(type=$type,locid=$locid) : nothing to remove", __FILE__, __LINE__, PEAR_LOG_DEBUG); - return false; - } - $lid = $dt->getObjectById($id); - $guid = $lid->get('globaluid'); - Horde::logMessage("SyncML: state->removeUID(type=$type,locid=$locid) : removing guid:$guid and lid:$lid", __FILE__, __LINE__, PEAR_LOG_DEBUG); - $dt->remove($guid); - $dt->remove($lid); - - return $guid; - } - - - /** - * This function should use DevINF information. - */ - function adjustContentType($type, $target = null) - { - if (is_array($type)) { - $ctype = $type['ContentType']; - $res = $type; - } else { - $ctype = $type; - $res = array(); - $res['ContentType'] = $ctype; - } - - $deviceInfo = $this->getClientDeviceInfo(); - $manufacturer = isset($deviceInfo['manufacturer']) ? strtolower($deviceInfo['manufacturer']) : 'unknown'; - switch ($manufacturer) { - case 'funambol': - // Funambol requires well-formed XML - $res['ContentFormat'] = 'strictxml'; - switch (strtolower($deviceInfo['model'])) { - case 'thunderbird': - case 'mozilla plugin': - $res['mayFragment'] = 1; - break; - default: - if (isset($deviceInfo['softwareVersion']) - && $deviceInfo['softwareVersion'] < 4.0) { - $res['mayFragment'] = 0; - } else { - $res['mayFragment'] = 1; - } - break; - } - break; - case 'patrick ohly': - // SyncEvolution requires HTML Encoding - $res['ContentFormat'] = 'htmlenc'; - default: - $res['mayFragment'] = 1; - $res['ContentFormat'] = 'strictxml'; - break; - } - - // the funambol specific types need to be encoded in base64 - switch (strtolower($ctype)) { - case 'text/x-s4j-sifc': - case 'text/x-s4j-sife': - case 'text/x-s4j-sift': - case 'text/x-s4j-sifn': - $res['ContentFormat'] = 'b64'; - break; - case 'text/vcard': - if ($manufacturer == 'nokia' || - isset($res['ContentVersion']) && $res['ContentVersion'] == '2.1') { - $res['ContentType'] = 'text/x-vcard'; - } - break; - case 'text/calendar': - if ($manufacturer == 'nokia' || - isset($res['ContentVersion']) && $res['ContentVersion'] == '1.0') { - $res['ContentType'] = 'text/x-vcalendar'; - } - } - return $res; - } - - function getPreferedContentType($type) - { - $_type = str_replace('./','',$type); - switch (strtolower($_type)) { - case 'contacts': - case 'contact': - case 'card': - return 'text/vcard'; - break; - - case 'notes': - case 'note': - return 'text/x-vnote'; - break; - - case 'calendar': - case 'events': - case 'event': - case 'tasks': - case 'task': - case 'jobs': - case 'caltasks': - return 'text/calendar'; - break; - - case 'sifcalendar': - case 'scal': - return 'text/x-s4j-sife'; - break; - - case 'sifcontacts': - case 'scard': - return 'text/x-s4j-sifc'; - break; - - case 'siftasks': - case 'stask': - return 'text/x-s4j-sift'; - break; - - case 'sifnotes': - case 'snote': - return 'text/x-s4j-sifn'; - break; - - default: - Horde::logMessage("SyncML: unrecognized content type '$_type'", __FILE__, __LINE__, PEAR_LOG_ERR); - break; - } - } - - function getHordeType($type) - { - $_type = str_replace('./','',$type); - switch(strtolower($_type)) - { - case 'contacts': - case 'contact': - case 'card': - return 'contacts'; - - case 'notes': - case 'note': - return 'notes'; - - case 'tasks': - case 'task': - case 'jobs': - return 'tasks'; - - case 'events': - case 'event': - case 'calendar': - return 'calendar'; - - case 'caltasks': - return 'caltasks'; - - # funambol related types - case 'sifcalendar': - case 'scal': - return 'sifcalendar'; - - case 'sifcontacts': - case 'scard': - return 'sifcontacts'; - - case 'siftasks': - case 'stask': - return 'siftasks'; - - case 'sifnotes': - case 'snote': - return 'sifnotes'; - - case 'configuration': - return 'configuration'; - - default: - Horde::logMessage("SyncML: unknown hordeType for type=$type ($_type)", __FILE__, __LINE__, PEAR_LOG_INFO); - } - return $_type; - } - - /** - * Returns the preferred contenttype of the client for the given - * sync data type (database). - * - * This is passed as an option to the Horde API export functions. - */ - - function getPreferedContentTypeClient($_sourceLocURI, $_targetLocURI = null) { - $deviceInfo = $this->getClientDeviceInfo(); - $_sourceLocURI = strtolower($_sourceLocURI); - - if(isset($deviceInfo['dataStore'][$_sourceLocURI]['maxGUIDSize']['contentType'])) { - $this->_maxGUIDSize = $deviceInfo['dataStore'][$this->_sourceURI]['maxGUIDSize']['contentType']; - } - - if(isset($deviceInfo['dataStore'][$_sourceLocURI]['rxPreference']['contentType'])) - { - $ctype = $deviceInfo['dataStore'][$_sourceLocURI]['rxPreference']['contentType']; - $cvers = $deviceInfo['dataStore'][$_sourceLocURI]['rxPreference']['contentVersion']; - $cfrmt = $deviceInfo['dataStore'][$_sourceLocURI]['rxPreference']['contentFormat']; - $cprops = $deviceInfo['dataStore'][$_sourceLocURI]['properties'][$ctype][$cvers]; - $cprops['UID']['NoTruncate'] = true; - /* - if (isset($deviceInfo['dataStore'][$_sourceLocURI]['maxGUIDSize'])) { - // get UID properties from maxGUIDSize - $cprops['UID']['Size'] = $deviceInfo['dataStore'][$_sourceLocURI]['maxGUIDSize']; - } - */ - $clientPrefs = array( - 'ContentType' => $ctype, - 'ContentVersion' => $cvers, - 'ContentFormat' => $cfrmt, - 'mayFragment' => 1, - 'Properties' => $cprops, - ); - - if ($_targetLocURI == 'configuration') $clientPrefs['ContentFormat'] = 'b64'; - - #Horde::logMessage('SyncML: sourceLocURI ' . $_sourceLocURI . " clientPrefs:\n" - # . print_r($clientPrefs, true), __FILE__, __LINE__, PEAR_LOG_DEBUG); - return $this->adjustContentType($clientPrefs, $_targetLocURI); - } - - Horde::logMessage('SyncML: sourceLocURI ' . $_sourceLocURI . " not found:\n" . print_r($deviceInfo, true), __FILE__, __LINE__, PEAR_LOG_DEBUG); - - if ($_targetLocURI != null) - { - return $this->adjustContentType($this->getPreferedContentType($_targetLocURI), $_targetLocURI); - } - - return PEAR::raiseError(_('sourceLocURI not found')); - } - - /** - * Returns the MaxGUIDSize of the client - */ - - function getMaxGUIDSizeClient() { - $maxGUIDSize = MAX_GUID_SIZE; - - if (isset($this->_maxGUIDSize)) { - $maxGUIDSize = $this->_maxGUIDSize; - } - return $maxGUIDSize; - } - - function setClientAnchorNext($type, $a) - { - $this->_clientAnchorNext[$type] = $a; - } - - function setServerAnchorLast($type, $a) - { - $this->_serverAnchorLast[$type] = $a; - } - - function setServerAnchorNext($type, $a) - { - $this->_serverAnchorNext[$type] = $a; - } - - function getClientAnchorNext($type) - { - return $this->_clientAnchorNext[$type]; - } - - function getServerAnchorNext($type) - { - return $this->_serverAnchorNext[$type]; - } - - function getServerAnchorLast($type) - { - return $this->_serverAnchorLast[$type]; - } - - /** - * Retrieves information about the previous sync if any. Returns - * false if no info found or a DateTreeObject with at least the - * following attributes: - * - * ClientAnchor: the clients Next Anchor of the previous sync. - * ServerAnchor: the Server Next Anchor of the previous sync. - */ - function &getSyncSummary($type) - { - $dt = &$this->getDataTree(); - - $id = $dt->getId($this->_locName . $this->_sourceURI . $type . 'syncSummary'); - if (is_a($id, 'PEAR_Error')) { - return false; - } - - return $dt->getObjectById($id); - } - - /** - * Retrieves information about the clients device info if any. Returns - * false if no info found or a DateTreeObject with at least the - * following attributes: - * - * a array containing all available infos about the device - */ - function getClientDeviceInfo() - { - if (isset($this->_clientDeviceInfo) && is_array($this->_clientDeviceInfo)) { - // use cached information - return $this->_clientDeviceInfo; - } - - $dt = &$this->getDataTree(); - - $id = $dt->getId($this->_locName . $this->_sourceURI . 'deviceInfo'); - if (is_a($id, 'PEAR_Error')) { - return false; - } - - $info = $dt->getObjectById($id); - - return $info->get('ClientDeviceInfo'); - } - - /** - * write clients device info to database - */ - function writeClientDeviceInfo() - { - if (!isset($this->_clientDeviceInfo) || - !is_array($this->_clientDeviceInfo) || - !empty($this->_clientDeviceInfo['persistent'])) { - return; - } - - $dt = &$this->getDataTree(); - - $s = $this->_locName . $this->_sourceURI . 'deviceInfo'; - $this->_clientDeviceInfo['persistent'] = true; - - // Set $locid. - $info = new DataTreeObject($s); - $info->set('ClientDeviceInfo', $this->_clientDeviceInfo); - $r = $dt->add($info); - if (is_a($r, 'PEAR_Error')) { - // Object already exists: update instead. - $dt->updateData($info); - } - } - - /** - * After a successful sync, the client and server's Next Anchors - * are written to the database so they can be used to negotiate - * upcoming syncs. - */ - function writeSyncSummary() - { - if (!isset($this->_serverAnchorNext) || !is_array($this->_serverAnchorNext)) { - return; - } - - $dt = &$this->getDataTree(); - - foreach (array_keys($this->_serverAnchorNext) as $type) { - $s = $this->_locName . $this->_sourceURI . $type . 'syncSummary'; - - // Set $locid. - $info = new DataTreeObject($s); - $info->set('ClientAnchor', $this->_clientAnchorNext); - $info->set('ServerAnchor', $this->_serverAnchorNext); - $r = $dt->add($info); - if (is_a($r, 'PEAR_Error')) { - // Object already exists: update instead. - $dt->updateData($info); - } - } - } - - /** - * The log simply counts the entries for each topic. - */ - function log($topic) - { - if (isset($this->_log[$topic])) { - $this->_log[$topic] += 1; - } else { - $this->_log[$topic] = 1; - } - } - - /** - * The Log is an array where the key is the event name and the - * value says how often this event occured. - */ - function getLog() - { - return $this->_log; - } - - /** - * Convert the content. - * - * Currently strips uid (primary key) information as client and - * server might use different ones. - * - * Charset conversions might be added here too. - */ - function convertClient2Server($content, $contentType) - { - switch ($contentType) { - case 'text/calendar': - case 'text/x-icalendar': - case 'text/x-vcalendar': - case 'text/x-vevent': - case 'text/x-vtodo': - // $content = preg_replace('/^UID:.*\n/m', '', $content, 1); - break; - } - - return $content; - } - - /** - * Convert the content. - * - * Currently strips uid (primary key) information as client and - * server might use different ones. - * - * Charset conversions might be added here too. - */ - function convertServer2Client($content, $contentType) - { - switch ($contentType) { - case 'text/calendar': - case 'text/x-icalendar': - case 'text/x-vcalendar': - case 'text/x-vevent': - case 'text/x-vtodo': - // $content = preg_replace('/^UID:.*\n/m', '', $content, 1); - break; - } - - // FIXME: utf8 really should be fine. But the P900 seems to - // expect ISO 8559 even when <?xml version="1.0" - // encoding="utf-8"> is specified. - // - // So at least make this dependant on the device information. - return utf8_decode($content); - } - - /** - * When True, Task Item changes (NAG) are sent to the server - * during "calendar" Syncs. That's the way the P800/900 handles - * things. Should be retrieved from devinf? - */ - function handleTasksInCalendar() - { - return true; - } - - /** - * This is a small helper function that can be included to check - * whether a given $obj is a PEAR_Error or not. If so, it logs - * to debug, var_dumps the $obj and exits. - */ - function dieOnError($obj, $file = __FILE__, $line = __LINE__) - { - if (!is_a($obj, 'PEAR_Error')) { - return; - } - - Horde::logMessage('SyncML: PEAR Error: ' . $obj->getMessage(), $file, $line, PEAR_LOG_ERR); - print "PEAR ERROR\n\n"; - var_dump($obj); - exit; - } - - function getAlert222Received() { - return $this->_receivedAlert222; - } - - function setAlert222Received($_status) { - $this->_receivedAlert222 = (bool)$_status; - } - - function incNumberOfElements() { - $this->_numberOfElements++; - } - - function clearNumberOfElements() { - $this->_numberOfElements = 0; - } - - function getNumberOfElements() { - if (isset($this->_numberOfElements)) { - return $this->_numberOfElements; - } else { - return false; - } - } - - function maxNumberOfElements() { - unset($this->_numberOfElements); - } -} diff --git a/phpgwapi/inc/horde/Horde/SyncML/State_egw.php b/phpgwapi/inc/horde/Horde/SyncML/State_egw.php deleted file mode 100644 index c2b909bcfb..0000000000 --- a/phpgwapi/inc/horde/Horde/SyncML/State_egw.php +++ /dev/null @@ -1,738 +0,0 @@ - - * @author Joerg Lehrke - * @version $Id$ - */ - -include_once dirname(__FILE__).'/State.php'; - -/** - * The EGW_SyncML_State class provides a SyncML state object. - */ -class EGW_SyncML_State extends Horde_SyncML_State -{ - var $table_devinfo = 'egw_syncmldevinfo'; - - /* - * store the mappings of egw uids to client uids - */ - var $uidMappings = array(); - - /* - * the domain of the current user - */ - var $_account_domain = 'default'; - - /** - * get the local content id from a syncid - * - * @param sting $_syncid id used in syncml - * @return int local egw content id - */ - function get_egwID($_syncid) { - $syncIDParts = explode('-',$_syncid); - array_shift($syncIDParts); - $_id = implode ('', $syncIDParts); - return $_id; - } - - /** - * when got a entry last added/modified/deleted - * - * @param $_syncid containing appName-contentid - * @param $_action string can be add, delete or modify - * @return string the last timestamp - */ - function getSyncTSforAction($_syncid, $_action) { - $syncIDParts = explode('-',$_syncid); - $_appName = array_shift($syncIDParts); - $_id = implode ('', $syncIDParts); - - $ts = $GLOBALS['egw']->contenthistory->getTSforAction($_appName, $_id, $_action); - - if (strstr($_id, ':')) { - // pseudo entries are related to parent entry - $parentId = array_shift(explode(':', $_id)); - $pts = $GLOBALS['egw']->contenthistory->getTSforAction($_appName, $parentId, $_action); - if ($pts > $ts) $ts = $pts; // We have changed the parent - } - return $ts; - } - - /** - * get the timestamp for action - * - * find which content changed since $_ts for application $_appName - * - * @param string$_appName the appname example: infolog_notes - * @param string $_action can be modify, add or delete - * @param string $_ts timestamp where to start searching from - * @param array $readableItems (optional) readable items of current user - * @return array containing syncIDs with changes - */ - function getHistory($_appName, $_action, $_ts, $readableItems = false) { - $guidList = array(); - $syncIdList = array(); - $userItems = false; - if (is_array($readableItems)) - { - $userItems = array(); - foreach($readableItems as $guid) - { - if (preg_match('/.*-(\d+)(:(\d+))?/', $guid, $matches)) - { - // We use only the real items' ids - $userItems[] = $matches[1]; - } - } - $userItems = array_unique($userItems); - } - $idList = $GLOBALS['egw']->contenthistory->getHistory($_appName, $_action, $_ts, $userItems); - foreach ($idList as $idItem) - { - if ($idItem) // ignore inconsistent entries - { - $syncIdList[] = $_appName . '-' . $idItem; - } - } - return $syncIdList; - } - - /** - * Returns the timestamp (if set) of the last change to the - * obj:guid, that was caused by the client. This is stored to - * avoid mirroring these changes back to the client. - */ - function getChangeTS($type, $guid) { - $mapID = $this->_locName . $this->_sourceURI . $type; - - #Horde::logMessage('SyncML: getChangeTS for ' . $mapID - # . ' / '. $guid, __FILE__, __LINE__, PEAR_LOG_DEBUG); - - if ($ts = $GLOBALS['egw']->db->select('egw_contentmap', 'map_timestamp', - array( - 'map_id' => $mapID, - 'map_guid' => $guid, - ), __LINE__, __FILE__, false, '', 'syncml')->fetchColumn()) { - #Horde::logMessage('SyncML: getChangeTS changets is ' - # . $GLOBALS['egw']->db->from_timestamp($ts), - # __FILE__, __LINE__, PEAR_LOG_DEBUG); - return $GLOBALS['egw']->db->from_timestamp($ts); - } - return false; - } - - /** - * Returns the exceptions for a GUID which the client knows of - */ - function getGUIDExceptions($type, $guid) { - $mapID = $this->_locName . $this->_sourceURI . $type; - - #Horde::logMessage('SyncML: getChangeTS for ' . $mapID - # . ' / '. $guid, __FILE__, __LINE__, PEAR_LOG_DEBUG); - - $guid_exceptions = array(); - $where = array ('map_id' => $mapID,); - $where[] = "map_guid LIKE '$guid" . ":%'"; - - // Fetch all exceptions which the client knows of - foreach ($GLOBALS['egw']->db->select('egw_contentmap', 'map_guid', $where, - __LINE__,__FILE__, false, '', 'syncml') as $row) - { - $parts = preg_split('/:/', $row['map_guid']); - $Id = $parts[0]; - $extension = $parts[1]; - $guid_exceptions[$extension] = $row['map_guid']; - } - return $guid_exceptions; - } - - /** - * Retrieves information about the clients device info if any. Returns - * false if no info found or a DateTreeObject with at least the - * following attributes: - * - * a array containing all available infos about the device - */ - function getClientDeviceInfo() { - #Horde::logMessage("SyncML: getClientDeviceInfo " . $this->_locName - # . ", " . $this->_sourceURI, __FILE__, __LINE__, PEAR_LOG_DEBUG); - - $syncml_prefs = $GLOBALS['egw_info']['user']['preferences']['syncml']; - $deviceMaxEntries = 'maxEntries-' . $this->_clientDeviceInfo['devId']; - $deviceUIDExtension = 'uidExtension-' . $this->_clientDeviceInfo['devId']; - $deviceNonBlockingAllday = 'nonBlockingAllday-' . $this->_clientDeviceInfo['devId']; - $deviceTimezone = 'tzid-' . $this->_clientDeviceInfo['devId']; - $deviceCharSet = 'charset-' . $this->_clientDeviceInfo['devId']; - if (isset($this->_clientDeviceInfo) - && is_array($this->_clientDeviceInfo)) { - // update user preferences - $this->_clientDeviceInfo['maxEntries'] = $syncml_prefs[$deviceMaxEntries]; - $this->_clientDeviceInfo['uidExtension'] = $syncml_prefs[$deviceUIDExtension]; - $this->_clientDeviceInfo['nonBlockingAllday'] = $syncml_prefs[$deviceNonBlockingAllday]; - $this->_clientDeviceInfo['tzid'] = $syncml_prefs[$deviceTimezone]; - $this->_clientDeviceInfo['charset'] = $syncml_prefs[$deviceCharSet]; - // use cached information - return $this->_clientDeviceInfo; - } - if (!($deviceID = $GLOBALS['egw']->db->select('egw_syncmldeviceowner', - 'owner_devid', - array ( - 'owner_locname' => $this->_locName, - 'owner_deviceid' => $this->_sourceURI, - ), __LINE__, __FILE__, false, '', 'syncml')->fetchColumn())) { - return false; - } - - $cols = array( - 'dev_dtdversion', - 'dev_numberofchanges', - 'dev_largeobjs', - 'dev_swversion', - 'dev_fwversion', - 'dev_hwversion', - 'dev_oem', - 'dev_model', - 'dev_manufacturer', - 'dev_devicetype', - 'dev_datastore', - 'dev_utc', - ); - - #Horde::logMessage("SyncML: getClientDeviceInfo $deviceID", __FILE__, __LINE__, PEAR_LOG_DEBUG); - - $where = array( - 'dev_id' => $deviceID, - ); - - - - if (($row = $GLOBALS['egw']->db->select('egw_syncmldevinfo', - $cols, $where, __LINE__, __FILE__, false, '', 'syncml')->fetch())) { - $this->_clientDeviceInfo = array ( - 'DTDVersion' => $row['dev_dtdversion'], - 'supportNumberOfChanges' => $row['dev_numberofchanges'], - 'supportLargeObjs' => $row['dev_largeobjs'], - 'UTC' => $row['dev_utc'], - 'softwareVersion' => $row['dev_swversion'], - 'hardwareVersion' => $row['dev_hwversion'], - 'firmwareVersion' => $row['dev_fwversion'], - 'oem' => $row['dev_oem'], - 'model' => $row['dev_model'], - 'manufacturer' => $row['dev_manufacturer'], - 'deviceType' => $row['dev_devicetype'], - 'maxMsgSize' => $this->_maxMsgSize, - 'maxEntries' => $syncml_prefs[$deviceMaxEntries], - 'uidExtension' => $syncml_prefs[$deviceUIDExtension], - 'nonBlockingAllday' => $syncml_prefs[$deviceNonBlockingAllday], - 'tzid' => $syncml_prefs[$deviceTimezone], - 'charset' => $syncml_prefs[$deviceCharSet], - 'devId' => $deviceID, - 'persistent' => $deviceID, - 'dataStore' => unserialize($row['dev_datastore']), - ); - return $this->_clientDeviceInfo; - } - return false; - } - - /** - * returns GUIDs of all client items - */ - function getClientItems($type=false) { - if (!$type) $type = $this->_targetURI; - $mapID = $this->_locName . $this->_sourceURI . $type; - - $guids = array(); - foreach($GLOBALS['egw']->db->select('egw_contentmap', 'map_guid', array( - 'map_id' => $mapID, - 'map_expired' => false, - ), __LINE__, __FILE__, false, '', 'syncml') as $row) { - $guids[] = $row['map_guid']; - } - return $guids; - } - - /** - * Retrieves the Horde server guid (like - * kronolith:0d1b415fc124d3427722e95f0e926b75) for a given client - * locid. Returns false if no such id is stored yet. - * - * Opposite of getLocId which returns the locid for a given guid. - */ - function getGlobalUID($type, $locid) { - $mapID = $this->_locName . $this->_sourceURI . $type; - - #Horde::logMessage('SyncML: search GlobalUID for ' . $mapID .' / '.$locid, __FILE__, __LINE__, PEAR_LOG_DEBUG); - - return $GLOBALS['egw']->db->select('egw_contentmap', 'map_guid', - array( - 'map_id' => $mapID, - 'map_locuid' => $locid, - 'map_expired' => false, - ), __LINE__, __FILE__, false, '', 'syncml')->fetchColumn(); - } - - /** - * Converts a EGW GUID (like - * kronolith:0d1b415fc124d3427722e95f0e926b75) to a client ID as - * used by the sync client (like 12) returns false if no such id - * is stored yet. - */ - function getLocID($type, $guid) { - $mapID = $this->_locName . $this->_sourceURI . $type; - - Horde::logMessage('SyncML: search LocID for ' . $mapID . ' / ' . $guid, __FILE__, __LINE__, PEAR_LOG_DEBUG); - - if (($locuid = $GLOBALS['egw']->db->select('egw_contentmap', 'map_locuid', array( - 'map_id' => $mapID, - 'map_guid' => $guid - ), __LINE__, __FILE__, false, '', 'syncml')->fetchColumn())) { - Horde::logMessage('SyncML: found LocID: '.$locuid, __FILE__, __LINE__, PEAR_LOG_DEBUG); - } - return $locuid; - } - - /** - * Retrieves information about the previous sync if any. Returns - * false if no info found or a DateTreeObject with at least the - * following attributes: - * - * ClientAnchor: the clients Next Anchor of the previous sync. - * ServerAnchor: the Server Next Anchor of the previous sync. - */ - function getSyncSummary($type) { - $deviceID = $this->_locName . $this->_sourceURI; - - Horde::logMessage("SyncML: getSyncSummary for $deviceID", __FILE__, __LINE__, PEAR_LOG_DEBUG); - - if (($row = $GLOBALS['egw']->db->select('egw_syncmlsummary', array('sync_serverts','sync_clientts'), array( - 'dev_id' => $deviceID, - 'sync_path' => $type - ), __LINE__, __FILE__, false, '', 'syncml')->fetch())) { - Horde::logMessage("SyncML: getSyncSummary for $deviceID serverts: ".$row['sync_serverts']." clients: ".$row['sync_clientts'], __FILE__, __LINE__, PEAR_LOG_DEBUG); - return array( - 'ClientAnchor' => $row['sync_clientts'], - 'ServerAnchor' => $row['sync_serverts'], - ); - } - return false; - } - - function isAuthorized() { - - if(!isset($this->_locName)) - { - Horde::logMessage('SyncML: Authentication not yet possible. Username not available', - __FILE__, __LINE__, PEAR_LOG_DEBUG); - return false; - } - - // store sessionID in a variable, because create() and verify() reset this value - $sessionID = session_id(); - - if (strpos($this->_locName,'@') === False) - { - $this->_account_domain = $GLOBALS['egw_info']['server']['default_domain']; - $this->_locName .= '@'. ($this->_account_domain ? $this->_account_domain : 'default'); - } - else - { - $parts = explode('@',$this->_locName); - $this->_account_domain = array_pop($parts); - } - - if (!is_object($GLOBALS['egw'])) - { - // Let the EGw core create the infrastructure classes - $_POST['login'] = $this->_locName; - $_REQUEST['domain'] = $this->_account_domain; - $GLOBALS['egw_info']['server']['default_domain'] = $this->_account_domain; - $GLOBALS['egw_info']['user']['domain'] = $this->_account_domain; - $GLOBALS['egw_info']['flags']['currentapp'] = 'login'; - $GLOBALS['egw_info']['flags']['noapi'] = false; - require_once(EGW_API_INC . '/functions.inc.php'); - } - - $GLOBALS['egw_info']['flags']['currentapp'] = 'syncml'; - - if (!$this->_isAuthorized) - { - - if (!isset($this->_password)) - { - Horde::logMessage('SyncML: Authentication not yet possible. Credetials missing', - __FILE__, __LINE__, PEAR_LOG_DEBUG); - return false; - } - - if ($GLOBALS['egw']->session->create($this->_locName,$this->_password,'text')) - { - if ($GLOBALS['egw_info']['user']['apps']['syncml']) - { - $this->_isAuthorized = 1; - // restore the original sessionID - session_regenerate_id(); - session_id($sessionID); - $GLOBALS['sessionid'] = $sessionID; - @session_start(); - Horde::logMessage('SyncML_EGW[' . $GLOBALS['sessionid'] - .']: Authentication of ' . $this->_locName . ' succeded', - __FILE__, __LINE__, PEAR_LOG_DEBUG); - $syncml_prefs = $GLOBALS['egw_info']['user']['preferences']['syncml']; - if (($deviceID = $GLOBALS['egw']->db->select('egw_syncmldeviceowner', - 'owner_devid', - array ( - 'owner_locname' => $this->_locName, - 'owner_deviceid' => $this->_sourceURI, - ), __LINE__, __FILE__, false, '', 'syncml')->fetchColumn())) { - $allowed_name = 'allowed-' . $deviceID; - if (isset($syncml_prefs[$allowed_name])) - { - $deviceAllowed = $syncml_prefs[$allowed_name]; - } - else - { - $deviceAllowed = -1; - } - } - else - { - $deviceAllowed = -1; // Unkown device - } - if (!$GLOBALS['egw_info']['user']['apps']['admin'] && - isset($syncml_prefs['deny_unknown_devices']) && - $syncml_prefs['deny_unknown_devices'] != 0) - { - if ($syncml_prefs['deny_unknown_devices'] == -1 && - $deviceAllowed != 1 || - $syncml_prefs['deny_unknown_devices'] == 1 && - $deviceAllowed == 0) - { - $this->_isAuthorized = -1; - Horde::logMessage('SyncML: Device is not allowed for user ' . $this->_locName, - __FILE__, __LINE__, PEAR_LOG_INFO); - } - } - } - else - { - $this->_isAuthorized = -1; // Authorization failed! - Horde::logMessage('SyncML is not enabled for user ' - . $this->_locName, __FILE__, __LINE__, PEAR_LOG_ERROR); - } - } - else - { - $this->_isAuthorized = -1; - Horde::logMessage('SyncML: Authentication of ' . $this->_locName - . ' failed', __FILE__, __LINE__, PEAR_LOG_INFO); - - } - - } - elseif ($this->_isAuthorized > 0) - { - if (!$GLOBALS['egw']->session->verify($sessionID, 'staticsyncmlkp3')) - { - Horde::logMessage('SyncML_EGW: egw session(' . $sessionID - . ') could not be not verified' , - __FILE__, __LINE__, PEAR_LOG_ERROR); - } - if (empty($GLOBALS['egw_info']['user']['passwd'])) - { - $GLOBALS['egw_info']['user']['passwd'] = $this->_password; - } - } - return ($this->_isAuthorized > 0); - } - - /** - * Removes all locid<->guid mappings for the given type. - * Returns always true. - */ - function removeAllUID($type) { - $mapID = $this->_locName . $this->_sourceURI . $type; - - Horde::logMessage("SyncML: state->removeAllUID(type=$type)", __FILE__, __LINE__, PEAR_LOG_DEBUG); - - $GLOBALS['egw']->db->delete('egw_contentmap', array('map_id' => $mapID), __LINE__, __FILE__, 'syncml'); - - return true; - } - - /** - * Used in SlowSync - * Removes all locid<->guid mappings for the given type, - * that are older than $ts. - * - * Returns always true. - */ - function removeOldUID($type, $ts) { - $mapID = $this->_locName . $this->_sourceURI . $type; - $where[] = "map_id = '".$mapID."' AND map_timestamp < '".$GLOBALS['egw']->db->to_timestamp($ts)."'"; - - Horde::logMessage("SyncML: state->removeOldUID(type=$type)", __FILE__, __LINE__, PEAR_LOG_DEBUG); - - $GLOBALS['egw']->db->delete('egw_contentmap', $where, __LINE__, __FILE__, 'syncml'); - - return true; - } - - /** - * Used at session end to cleanup expired entries - * Removes all locid<->guid mappings for the given type, - * that are marked as expired and older than $ts. - * - * Returns always true. - */ - function removeExpiredUID($type, $ts) { - $mapID = $this->_locName . $this->_sourceURI . $type; - $where['map_id'] = $mapID; - $where['map_expired'] = true; - $where[] = "map_timestamp <= '".$GLOBALS['egw']->db->to_timestamp($ts)."'"; - - Horde::logMessage("SyncML: state->removeExpiredUID(type=$type)", - __FILE__, __LINE__, PEAR_LOG_DEBUG); - - $GLOBALS['egw']->db->delete('egw_contentmap', $where, - __LINE__, __FILE__, 'syncml'); - - return true; - } - - /** - * Check if an entry is already expired - * - * Returns true for expired mappings. - */ - function isExpiredUID($type, $locid) { - $mapID = $this->_locName . $this->_sourceURI . $type; - $expired = false; - $where = array( - 'map_id' => $mapID, - 'map_locuid' => $locid, - ); - if (($expired = $GLOBALS['egw']->db->select('egw_contentmap', 'map_expired', - $where, __LINE__, __FILE__, false, '', 'syncml')->fetchColumn())) { - Horde::logMessage('SyncML: found LocID: '. $locid, - __FILE__, __LINE__, PEAR_LOG_DEBUG); - } - return $expired; - } - - /** - * Removes the locid<->guid mapping for the given locid. Returns - * the guid that was removed or false if no mapping entry was - * found. - */ - function removeUID($type, $locid) { - $mapID = $this->_locName . $this->_sourceURI . $type; - - $where = array ( - 'map_id' => $mapID, - 'map_locuid' => $locid - ); - - if (!($guid = $GLOBALS['egw']->db->select('egw_contentmap', 'map_guid', $where, - __LINE__, __FILE__, false, '', 'syncml')->fetchColumn())) { - Horde::logMessage("SyncML: state->removeUID(type=$type,locid=$locid)" - . " nothing to remove", __FILE__, __LINE__, PEAR_LOG_INFO); - return false; - } - - Horde::logMessage("SyncML: state->removeUID(type=$type,locid=$locid): " - . "removing guid $guid", __FILE__, __LINE__, PEAR_LOG_DEBUG); - - $GLOBALS['egw']->db->delete('egw_contentmap', $where, __LINE__, __FILE__, 'syncml'); - - return $guid; - } - - /** - * Puts a given client $locid and Horde server $guid pair into the - * map table to allow mapping between the client's and server's - * IDs. Actually there are two maps: from the localid to the guid - * and vice versa. The localid is converted to a key as follows: - * this->_locName . $this->_sourceURI . $type . $locid so you can - * have different syncs with different devices. If an entry - * already exists, it is overwritten. - * Expired entries can be deleted at the next session start. - */ - function setUID($type, $locid, $_guid, $ts=0, $expired=false) { - #Horde::logMessage("SyncML: setUID $type, $locid, $_guid, $ts ", __FILE__, __LINE__, PEAR_LOG_DEBUG); - - if (!strlen("$_guid")) { - // We can't handle this case otherwise - return; - } - - // problem: entries created from client, come here with the (long) server guid, - // but getUIDMapping does not know them and can not map server-guid <--> client guid - $guid = $this->getUIDMapping($_guid); - if($guid === false) { - // this message is not really usefull here because setUIDMapping is only called when adding content to the client, - // however setUID is called also when adding content from the client. So in all other conditions this - // message will be logged. - //Horde::logMessage("SyncML: setUID $type, $locid, $guid something went wrong!!! Mapping not found.", __FILE__, __LINE__, PEAR_LOG_INFO); - $guid = $_guid; - //return false; - } - #Horde::logMessage("SyncML: setUID $_guid => $guid", __FILE__, __LINE__, PEAR_LOG_DEBUG); - - if(!$ts) $ts = time(); - - Horde::logMessage("SyncML: setUID $type, $locid, $guid, $ts ", - __FILE__, __LINE__, PEAR_LOG_DEBUG); - - $mapID = $this->_locName . $this->_sourceURI . $type; - - // expire all client id's - $where = array( - 'map_id' => $mapID, - 'map_locuid' => $locid, - ); - $GLOBALS['egw']->db->delete('egw_contentmap', $where, - __LINE__, __FILE__, 'syncml'); - - // expire old EGw id's - $where = array( - 'map_id' => $mapID, - 'map_guid' => $guid, - ); - $GLOBALS['egw']->db->delete('egw_contentmap', $where, - __LINE__, __FILE__, 'syncml'); - /* - $data = array ('map_expired' => true); - $GLOBALS['egw']->db->update('egw_contentmap', $data, $where, - __LINE__, __FILE__, 'syncml'); - */ - $data = $where + array( - 'map_locuid' => $locid, - 'map_timestamp' => $ts, - 'map_expired' => ($expired ? true : false), - ); - $GLOBALS['egw']->db->insert('egw_contentmap', $data, $where, - __LINE__, __FILE__, 'syncml'); - } - - /** - * writes clients deviceinfo into database - */ - function writeClientDeviceInfo() { - if (!isset($this->_clientDeviceInfo) - || !is_array($this->_clientDeviceInfo)) { - return false; - } - - if (!isset($this->_clientDeviceInfo['persistent'])) { - // the device information was updated - - if(!isset($this->size_dev_hwversion)) { - $tableDefDevInfo = $GLOBALS['egw']->db->get_table_definitions('syncml',$this->table_devinfo); - $this->size_dev_hwversion = $tableDefDevInfo['fd']['dev_hwversion']['precision']; - unset($tableDefDevInfo); - } - - $softwareVersion = !empty($this->_clientDeviceInfo['softwareVersion']) ? $this->_clientDeviceInfo['softwareVersion'] : ''; - $hardwareVersion = !empty($this->_clientDeviceInfo['hardwareVersion']) ? substr($this->_clientDeviceInfo['hardwareVersion'], 0, $this->size_dev_hwversion) : ''; - $firmwareVersion = !empty($this->_clientDeviceInfo['firmwareVersion']) ? $this->_clientDeviceInfo['firmwareVersion'] : ''; - - $where = array( - 'dev_model' => $this->_clientDeviceInfo['model'], - 'dev_manufacturer' => $this->_clientDeviceInfo['manufacturer'], - 'dev_swversion' => $softwareVersion, - 'dev_hwversion' => $hardwareVersion, - 'dev_fwversion' => $firmwareVersion, - ); - - if (($deviceID = $GLOBALS['egw']->db->select('egw_syncmldevinfo', 'dev_id', $where, - __LINE__, __FILE__, false, '', 'syncml')->fetchColumn())) { - $data = array ( - 'dev_datastore' => serialize($this->_clientDeviceInfo['dataStore']), - ); - $GLOBALS['egw']->db->update('egw_syncmldevinfo', $data, $where, - __LINE__, __FILE__, 'syncml'); - } else { - $data = array ( - 'dev_dtdversion' => $this->_clientDeviceInfo['DTDVersion'], - 'dev_numberofchanges' => ($this->_clientDeviceInfo['supportNumberOfChanges'] ? true : false), - 'dev_largeobjs' => ($this->_clientDeviceInfo['supportLargeObjs'] ? true : false), - 'dev_utc' => ($this->_clientDeviceInfo['UTC'] ? true : false), - 'dev_swversion' => $softwareVersion, - 'dev_hwversion' => $hardwareVersion, - 'dev_fwversion' => $firmwareVersion, - 'dev_oem' => $this->_clientDeviceInfo['oem'], - 'dev_model' => $this->_clientDeviceInfo['model'], - 'dev_manufacturer' => $this->_clientDeviceInfo['manufacturer'], - 'dev_devicetype' => $this->_clientDeviceInfo['deviceType'], - 'dev_datastore' => serialize($this->_clientDeviceInfo['dataStore']), - ); - $GLOBALS['egw']->db->insert('egw_syncmldevinfo', $data, $where, __LINE__, __FILE__, 'syncml'); - - $deviceID = $GLOBALS['egw']->db->get_last_insert_id('egw_syncmldevinfo', 'dev_id'); - } - - $this->_clientDeviceInfo['persistent'] = $deviceID; - } - - $data = $where = array ( - 'owner_locname' => $this->_locName, - 'owner_deviceid' => $this->_sourceURI, - ); - - $GLOBALS['egw']->db->delete('egw_syncmldeviceowner', $where, - __LINE__, __FILE__, 'syncml'); - - $data['owner_devid'] = $this->_clientDeviceInfo['persistent']; - - $GLOBALS['egw']->db->insert('egw_syncmldeviceowner', $data, $where, - __LINE__, __FILE__, 'syncml'); - } - - /** - * After a successful sync, the client and server's Next Anchors - * are written to the database so they can be used to negotiate - * upcoming syncs. - */ - function writeSyncSummary() { - #parent::writeSyncSummary(); - - if (!isset($this->_serverAnchorNext) - || !is_array($this->_serverAnchorNext)) { - return; - } - - $deviceID = $this->_locName . $this->_sourceURI; - - foreach((array)$this->_serverAnchorNext as $type => $a) { - Horde::logMessage("SyncML: write SYNCSummary for $deviceID " - . "$type serverts: $a clients: " - . $this->_clientAnchorNext[$type], - __FILE__, __LINE__, PEAR_LOG_DEBUG); - - $where = array( - 'dev_id' => $deviceID, - 'sync_path' => $type, - ); - - $data = array( - 'sync_serverts' => $a, - 'sync_clientts' => $this->_clientAnchorNext[$type] - ); - - $GLOBALS['egw']->db->insert('egw_syncmlsummary', $data, $where, - __LINE__, __FILE__, 'syncml'); - } - } -} diff --git a/phpgwapi/inc/horde/Horde/SyncML/Sync.php b/phpgwapi/inc/horde/Horde/SyncML/Sync.php deleted file mode 100644 index 1fff5eaa90..0000000000 --- a/phpgwapi/inc/horde/Horde/SyncML/Sync.php +++ /dev/null @@ -1,467 +0,0 @@ - - * @author Joerg Lehrke - * @copyright (c) The Horde Project (http://www.horde.org/) - * @version $Id$ - */ - -class Horde_SyncML_Sync { - - /** - * Target, either contacts, notes, events, - */ - var $_targetLocURI; - - var $_sourceLocURI; - - var $_locName; - - /** - * The synchronization method, one of the ALERT_* constants. - * - * @var integer - */ - var $_syncType; - - /** - * Return if all commands success. - */ - var $globalSuccess; - - /** - * This is the content type to use to export data. - */ - var $preferedContentType; - - /** - * Optional filter expression for this content. - * - * @var string - */ - var $_filterExpression = ''; - - - - /** - * Do have the sync data loaded from the database already? - */ - var $syncDataLoaded; - - function &factory($alert) { - Horde::logMessage('SyncML: new sync for alerttype ' . $alert, __FILE__, __LINE__, PEAR_LOG_DEBUG); - switch ($alert) { - case ALERT_TWO_WAY: - include_once 'Horde/SyncML/Sync/TwoWaySync.php'; - return $sync = new Horde_SyncML_Sync_TwoWaySync(); - - case ALERT_SLOW_SYNC: - include_once 'Horde/SyncML/Sync/SlowSync.php'; - return $sync = new Horde_SyncML_Sync_SlowSync(); - - case ALERT_ONE_WAY_FROM_CLIENT: - include_once 'Horde/SyncML/Sync/OneWayFromClientSync.php'; - return $sync = new Horde_SyncML_Sync_OneWayFromClientSync(); - - case ALERT_REFRESH_FROM_CLIENT: - include_once 'Horde/SyncML/Sync/RefreshFromClientSync.php'; - return $sync = new Horde_SyncML_Sync_RefreshFromClientSync(); - - case ALERT_ONE_WAY_FROM_SERVER: - include_once 'Horde/SyncML/Sync/OneWayFromServerSync.php'; - return $sync = new Horde_SyncML_Sync_OneWayFromServerSync(); - - case ALERT_REFRESH_FROM_SERVER: - include_once 'Horde/SyncML/Sync/RefreshFromServerSync.php'; - return $sync = new Horde_SyncML_Sync_RefreshFromServerSync(); - } - - require_once 'PEAR.php'; - return PEAR::raiseError('Alert ' . $alert . ' not found.'); - } - - function nextSyncCommand($currentCmdID, &$syncCommand, &$output) { - $this->runSyncCommand($syncCommand); - if ($syncCommand->hasMoreData()) { - Horde::logMessage('SyncML: moreData: TRUE', __FILE__, __LINE__, PEAR_LOG_DEBUG); - $syncCommand->setStatus(RESPONSE_CHUNKED_ITEM_ACCEPTED_AND_BUFFERED); - } - return $syncCommand->output($currentCmdID, $output); - } - - function startSync($currentCmdID, &$output) { - return $currentCmdID; - } - - function endSync($currentCmdID, &$output) { - return $currentCmdID; - } - - /** - * Setter for property sourceURI. - * - * @param string $sourceURI New value of property sourceLocURI. - */ - function setSourceLocURI($sourceURI) { - $this->_sourceLocURI = $sourceURI; - } - - /** - * Get sourceURI. - * - * @return string $sourceURI or false on error. - */ - function getSourceLocURI() { - if (empty($this->_sourceLocURI)) { - return false; - } - return $this->_sourceLocURI; - } - - /** - * Setter for property targetURI. - * - * @param string $targetURI New value of property targetLocURI. - */ - function setTargetLocURI($targetURI) { - $this->_targetLocURI = $targetURI; - } - - /** - * Setter for property syncType. - * - * @param integer $syncType New value of property syncType. - */ - function setSyncType($syncType) { - $this->_syncType = $syncType; - } - - /** - * Setter for property locName. - * - * @param string $locName New value of property locName. - */ - function setLocName($locName) { - $this->_locName = $locName; - } - - /** - * Setter for property filterExpression. - * - * @param string $expression New value of property filterExpression. - */ - function setFilterExpression($expression) { - $this->_filterExpression = $expression; - } - - /** - * Here's where the actual processing of a client-sent Sync - * Command takes place. Entries are added, deleted or replaced - * from the server database by using Horde API (Registry) calls. - */ - function runSyncCommand(&$command) { - global $registry; - $history = $GLOBALS['egw']->contenthistory; - $state = &$_SESSION['SyncML.state']; - - - $type = $this->_targetLocURI; - - $syncml_prefs = $GLOBALS['egw_info']['user']['preferences']['syncml']; - if (isset($syncml_prefs[$type])) { - $sync_conflicts = $syncml_prefs[$type]; - } else { - $sync_conflicts = CONFLICT_SERVER_WINNING; - } - - $state->setLocName($this->_locName); - $locName = $state->getLocName(); - $sourceURI = $state->getSourceURI(); - $hordeType = $state->getHordeType($type); - $serverAnchorLast = $state->getServerAnchorLast($type); - $changes = array(); - foreach($state->getChangedItems($type) as $change) { - // now we have to remove the ones - // that came from the last sync with this client - $guid_ts = $state->getSyncTSforAction($change, 'modify'); - $sync_ts = $state->getChangeTS($type, $change); - if ($sync_ts && $sync_ts == $guid_ts) { - // Change was done by us upon request of client. - Horde::logMessage("SyncML: change: $change ignored, " . - "came from client", __FILE__, __LINE__, PEAR_LOG_DEBUG); - continue; - } - $changes[] = $change; - } - - Horde::logMessage('SyncML: runSyncCommand found ' . count($changes) . - " possible conflicts for $type", __FILE__, __LINE__, PEAR_LOG_DEBUG); - - if(!$contentType = $command->getContentType()) { - $contentType = $state->getPreferedContentType($type); - } - - if (($contentType == 'text/x-vcalendar' || $contentType == 'text/calendar') - && strpos($command->getContent(), 'BEGIN:VTODO') !== false) { - $hordeType = 'tasks'; - } - - $syncElementItems = $command->getSyncElementItems(); - - foreach($syncElementItems as $syncItem) { - - $guid = false; - $locURI = $syncItem->getLocURI(); - - if (is_a($command, 'Horde_SyncML_Command_Sync_Add')) { - if ($sync_conflicts > CONFLICT_RESOLVED_WITH_DUPLICATE) { - // We enforce the client not to change anything - if ($sync_conflicts > CONFLICT_CLIENT_CHANGES_IGNORED) { - // delete this item from client - Horde::logMessage("SyncML: Server RO! REMOVE $locURI from client", - __FILE__, __LINE__, PEAR_LOG_WARNING); - $state->addConflictItem($type, $locURI); - } else { - Horde::logMessage('SyncML: Server RO! ' - . 'REJECT all client changes', - __FILE__, __LINE__, PEAR_LOG_WARNING); - $state->log('Client-AddReplaceIgnored'); - } - continue; - } - - $guid = $registry->call($hordeType . '/import', - array($state->convertClient2Server($syncItem->getContent(), $contentType), $contentType)); - - if (!is_a($guid, 'PEAR_Error') && $guid != false) { - $ts = $state->getSyncTSforAction($guid, 'add'); - $state->setUID($type, $locURI, $guid, $ts); - $state->log('Client-Add'); - Horde::logMessage("SyncML: added client entry $locURI as $guid", - __FILE__, __LINE__, PEAR_LOG_DEBUG); - } else { - $state->log('Client-AddFailure'); - Horde::logMessage('SyncML: Error in adding client entry ' . $locURI . ': ' - . $guid->message, __FILE__, __LINE__, PEAR_LOG_ERR); - } - } elseif (is_a($command, 'Horde_SyncML_Command_Sync_Delete')) { - $guid = $state->removeUID($type, $locURI); - if (!$guid) { - // the entry is no longer on the server - $state->log('Client-DeleteFailure'); - Horde::logMessage('SyncML: Failure deleting client entry ' . $locURI - . ', gone on server already!', - __FILE__, __LINE__, PEAR_LOG_ERR); - continue; - } - if ($sync_conflicts > CONFLICT_RESOLVED_WITH_DUPLICATE) { - // We enforce the client not to change anything - if ($sync_conflicts > CONFLICT_CLIENT_CHANGES_IGNORED) { - Horde::logMessage('SyncML: Server RO! ADD ' - . $guid . ' to client again', - __FILE__, __LINE__, PEAR_LOG_WARNING); - $state->pushAddedItem($type, $guid); - } else { - Horde::logMessage('SyncML: '. - 'Server RO! REJECT all client changes', - __FILE__, __LINE__, PEAR_LOG_WARNING); - } - $state->log('Client-DeleteIgnored'); - continue; - } - elseif ($sync_conflicts == CONFLICT_RESOLVED_WITH_DUPLICATE && - in_array($guid, $changes)) - { - Horde::logMessage('SyncML: '. - 'Server has updated version to keep', - __FILE__, __LINE__, PEAR_LOG_WARNING); - $state->log('Client-DeleteIgnored'); - continue; - } - elseif ($sync_conflicts == CONFLICT_MERGE_DATA) - { - Horde::logMessage('SyncML: Server Merge Only: ADD ' - . $guid . ' to client again', - __FILE__, __LINE__, PEAR_LOG_WARNING); - $state->pushAddedItem($type, $guid); - $state->log('Client-DeleteIgnored'); - continue; - } - - Horde::logMessage('SyncML: about to delete entry ' - . $type .' / '. $guid . ' due to client request ' - . $syncItem->getLocURI(), __FILE__, __LINE__, PEAR_LOG_DEBUG); - - if (!is_a($guid, 'PEAR_Error') && $guid != false) { - $registry->call($hordeType . '/delete', array($guid)); - $ts = $state->getSyncTSforAction($guid, 'delete'); - $state->setUID($type, $locURI, $guid, $ts, 1); - $state->log('Client-Delete'); - Horde::logMessage('SyncML: deleted entry ' - . $guid . ' due to client request', - __FILE__, __LINE__, PEAR_LOG_DEBUG); - } else { - $state->log('Client-DeleteFailure'); - Horde::logMessage('SyncML: Failure deleting client entry ' . $locURI - . ', maybe gone on server already: ' - . $guid->message, __FILE__, __LINE__, PEAR_LOG_ERR); - } - } elseif (is_a($command, 'Horde_SyncML_Command_Sync_Replace')) { - $guid = $state->getGlobalUID($type, $locURI); - $replace = true; - $ok = false; - $merge = false; - if ($hordeType == 'configuration') - { - $command->setStatus(RESPONSE_ALREADY_EXISITS); - } - if ($guid) - { - Horde::logMessage('SyncML: locuri '. $locURI . ' guid ' . $guid , __FILE__, __LINE__, PEAR_LOG_DEBUG); - if (($sync_conflicts > CONFLICT_RESOLVED_WITH_DUPLICATE) || in_array($guid, $changes)) - { - Horde::logMessage('SyncML: CONFLICT for locuri ' . $locURI . ' guid ' . $guid , __FILE__, __LINE__, PEAR_LOG_WARNING); - switch ($sync_conflicts) - { - case CONFLICT_CLIENT_WINNING: - $command->setStatus(RESPONSE_CONFLICT_RESOLVED_WITH_CLIENT_WINS); - break; - case CONFLICT_SERVER_WINNING: - Horde::logMessage('SyncML: REJECT client change for locuri ' . - $locURI . ' guid ' . $guid , - __FILE__, __LINE__, PEAR_LOG_WARNING); - $command->setStatus(RESPONSE_CONFLICT_RESOLVED_WITH_SERVER_WINS); - $ok = true; - $replace = false; - $state->log('Client-AddReplaceIgnored'); - break; - case CONFLICT_MERGE_DATA: - Horde::logMessage('SyncML: Merge server and client data for locuri ' . - $locURI . ' guid ' . $guid , - __FILE__, __LINE__, PEAR_LOG_WARNING); - $command->setStatus(RESPONSE_CONFLICT_RESOLVED_WITH_MERGE); - $merge = true; - break; - case CONFLICT_RESOLVED_WITH_DUPLICATE: - $replace = false; - break; - case CONFLICT_CLIENT_CHANGES_IGNORED: - Horde::logMessage('SyncML: Server RO! REJECT client change for locuri ' . - $locURI . ' guid ' . $guid , - __FILE__, __LINE__, PEAR_LOG_WARNING); - $command->setStatus(RESPONSE_PERMISSION_DENIED); - $ok = true; - $replace = false; - $ts = $state->getSyncTSforAction($guid, 'modify'); - $state->setUID($type, $locURI, $guid, $ts); - $state->log('Client-AddReplaceIgnored'); - break; - default: // We enforce our data on client - Horde::logMessage('SyncML: Server RO! UNDO client change for locuri ' . - $locURI . ' guid ' . $guid , - __FILE__, __LINE__, PEAR_LOG_WARNING); - $command->setStatus(RESPONSE_PERMISSION_DENIED); - $state->pushChangedItem($type, $guid); - $ok = true; - $replace = false; - } - } - elseif ($sync_conflicts == CONFLICT_MERGE_DATA) - { - Horde::logMessage('SyncML: Merge server and client data for locuri ' . - $locURI . ' guid ' . $guid , - __FILE__, __LINE__, PEAR_LOG_WARNING); - $merge = true; - } - - if ($replace) - { - // Entry exists: replace/merge with current one. - $ok = $registry->call($hordeType . '/replace', - array($guid, $state->convertClient2Server($syncItem->getContent(), - $contentType), $contentType, $type, $merge)); - if (!is_a($ok, 'PEAR_Error') && $ok != false) - { - $ts = $state->getSyncTSforAction($guid, 'modify'); - $state->setUID($type, $locURI, $guid, $ts); - if ($merge) - { - Horde::logMessage('SyncML: Merged entry ' . $locURI . ' due to client request guid: ' . - $guid . ' ts: ' . $ts, __FILE__, __LINE__, PEAR_LOG_DEBUG); - } - else - { - Horde::logMessage('SyncML: replaced entry ' . $locURI . ' due to client request guid: ' . - $guid . ' ts: ' . $ts, __FILE__, __LINE__, PEAR_LOG_DEBUG); - } - $state->log('Client-Replace'); - $ok = true; - } - else - { - // Entry may have been deleted; try adding it. - $ok = false; - } - } - } - - if (!$ok) { - // Entry does either not exist in map or database, or should be added due to a conflict - - if ($sync_conflicts > CONFLICT_RESOLVED_WITH_DUPLICATE) { - // We enforce the client not to change anything - if ($sync_conflicts > CONFLICT_CLIENT_CHANGES_IGNORED) { - // delete this item from client - Horde::logMessage('SyncML: Server RO! REMOVE ' . $locURI . ' from client', - __FILE__, __LINE__, PEAR_LOG_WARNING); - $state->addConflictItem($type, $syncItem->getLocURI()); - } else { - Horde::logMessage('SyncML: Server RO! REJECT all client changes', - __FILE__, __LINE__, PEAR_LOG_WARNING); - } - continue; - } - Horde::logMessage('SyncML: try to add contentype ' - . $contentType . ' for locuri ' . $locURI, - __FILE__, __LINE__, PEAR_LOG_DEBUG); - //continue; - $oguid = $guid; - $guid = $registry->call($hordeType . '/import', - array($state->convertClient2Server($syncItem->getContent(), $contentType), $contentType, $guid)); - if (!is_a($guid, 'PEAR_Error')) { - if ($oguid != $guid) { - // We add a new entry - $ts = $state->getSyncTSforAction($guid, 'add'); - Horde::logMessage('SyncML: added entry ' . $locURI . ' guid ' - . $guid . ' from client', - __FILE__, __LINE__, PEAR_LOG_DEBUG); - $state->log('Client-Add'); - } else { - // We replaced an entry - $ts = $state->getSyncTSforAction($guid, 'modify'); - Horde::logMessage('SyncML: replaced entry ' . $locURI . ' guid ' - . $guid . ' from client', - __FILE__, __LINE__, PEAR_LOG_DEBUG); - $state->log('Client-Replace'); - } - $state->setUID($type, $locURI, $guid, $ts); - } else { - Horde::logMessage('SyncML: Error in replacing/' - . 'add client entry ' . $locURI . ' : ' . $guid->message, - __FILE__, __LINE__, PEAR_LOG_ERR); - $state->log('Client-AddFailure'); - } - } - } - } - } -} diff --git a/phpgwapi/inc/horde/Horde/SyncML/Sync/OneWayFromClientSync.php b/phpgwapi/inc/horde/Horde/SyncML/Sync/OneWayFromClientSync.php deleted file mode 100644 index 6d69bd02b5..0000000000 --- a/phpgwapi/inc/horde/Horde/SyncML/Sync/OneWayFromClientSync.php +++ /dev/null @@ -1,23 +0,0 @@ - - * - * 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 Anthony Mills - * @version $Revision$ - * @since Horde 3.0 - * @package Horde_SyncML - */ -class Horde_SyncML_Sync_OneWayFromClientSync extends Horde_SyncML_Sync { - -} diff --git a/phpgwapi/inc/horde/Horde/SyncML/Sync/OneWayFromServerSync.php b/phpgwapi/inc/horde/Horde/SyncML/Sync/OneWayFromServerSync.php deleted file mode 100644 index 65f963b48f..0000000000 --- a/phpgwapi/inc/horde/Horde/SyncML/Sync/OneWayFromServerSync.php +++ /dev/null @@ -1,22 +0,0 @@ - - * - * 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 Anthony Mills - * @version $Revision$ - * @since Horde 3.0 - * @package Horde_SyncML - */ -class Horde_SyncML_Sync_OneWayFromServerSync extends Horde_SyncML_Sync_TwoWaySync { -} diff --git a/phpgwapi/inc/horde/Horde/SyncML/Sync/RefreshFromClientSync.php b/phpgwapi/inc/horde/Horde/SyncML/Sync/RefreshFromClientSync.php deleted file mode 100644 index e9ef2c0c23..0000000000 --- a/phpgwapi/inc/horde/Horde/SyncML/Sync/RefreshFromClientSync.php +++ /dev/null @@ -1,23 +0,0 @@ - - * - * 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 Anthony Mills - * @version $Revision$ - * @since Horde 3.0 - * @package Horde_SyncML - */ -class Horde_SyncML_Sync_RefreshFromClientSync extends Horde_SyncML_Sync_SlowSync { - /** - * We needed to erase the current server contents, then we can add - * the client's contents. - */ -} diff --git a/phpgwapi/inc/horde/Horde/SyncML/Sync/RefreshFromServerSync.php b/phpgwapi/inc/horde/Horde/SyncML/Sync/RefreshFromServerSync.php deleted file mode 100644 index bb0cc88951..0000000000 --- a/phpgwapi/inc/horde/Horde/SyncML/Sync/RefreshFromServerSync.php +++ /dev/null @@ -1,187 +0,0 @@ - - * @author Joerg Lehrke - * @copyright (c) The Horde Project (http://www.horde.org/) - * @version $Id$ - */ -include_once 'Horde/SyncML/Sync.php'; - -class Horde_SyncML_Sync_RefreshFromServerSync extends Horde_SyncML_Sync_TwoWaySync { - function handleSync($currentCmdID, $hordeType, $syncType, &$output, $refts) { - global $registry; - - $state = &$_SESSION['SyncML.state']; - $maxMsgSize = $state->getMaxMsgSizeClient(); - $deviceInfo = $state->getClientDeviceInfo(); - - if (isset($deviceInfo['maxEntries'])) { - $maxEntries = $deviceInfo['maxEntries']; - if (!$maxMsgSize && !$maxEntries) { - // fallback to default - $maxEntries = MAX_ENTRIES; - } - } else { - $maxEntries = MAX_ENTRIES; - } - - $serverAnchorNext = $state->getServerAnchorNext($syncType); - - if (isset($state->curSyncItem)) { - // Finish the pending sync item - $cmd = &$state->curSyncItem; - if (!is_a($cmd, 'Horde_SyncML_Command_Sync_ContentSyncElement')) { - // Conflict with other datastore - Horde :: logMessage("SyncML: handleSync($currentCmdID, $hordeType, $syncType) moreData conflict found", - __FILE__, __LINE__, PEAR_LOG_WARNING); - $state->setSyncStatus(SERVER_SYNC_DATA_PENDING); - return $currentCmdID; - } - unset($state->curSyncItem); - $currentCmdID = $cmd->outputCommand($currentCmdID, $output, 'Sync'); - - // moreData split; save in session state and end current message - if ($cmd->hasMoreData()) { - $state->curSyncItem = &$cmd; - $state->setSyncStatus(SERVER_SYNC_DATA_PENDING); - return $currentCmdID; - } - $state->incNumberOfElements(); - } - - $adds = &$state->getAddedItems($syncType); - Horde::logMessage("SyncML: ".count($adds). - ' added items found for '.$syncType , - __FILE__, __LINE__, PEAR_LOG_DEBUG); - - if(is_array($adds)) { - while($guid = array_shift($adds)) { - $currentSize = $output->getOutputSize(); - // return if we have to much data - if (($maxEntries && ($state->getNumberOfElements() >= $maxEntries) - && isset($contentType['mayFragment']) - && $contentType['mayFragment']) - || ($maxMsgSize - && (($currentSize + MIN_MSG_LEFT * 2) > $maxMsgSize))) { - // put the item back in the queue - $adds[] = $guid; - $state->maxNumberOfElements(); - $state->setSyncStatus(SERVER_SYNC_DATA_PENDING); - return $currentCmdID; - } - - if ($locID = $state->getLocID($syncType, $guid)) { - Horde::logMessage("SyncML: RefreshFromServerSync add to client: $guid ignored, already at client($locID)", - __FILE__, __LINE__, PEAR_LOG_DEBUG); - continue; - } - - $guid_ts = $state->getSyncTSforAction($guid, 'add'); - if ($guid_ts > $serverAnchorNext) { - // Change was made after we started this sync. - // Don't sent this now to the client. - Horde::logMessage("SyncML: RefreshFromServerSync add $guid is in our future", - __FILE__, __LINE__, PEAR_LOG_DEBUG); - continue; - } - - $contentType = $state->getPreferedContentTypeClient($this->_sourceLocURI, $this->_targetLocURI); - $c = $registry->call($hordeType . '/export', array('guid' => $guid, 'contentType' => $contentType)); - - if ($c === false) continue; // no content to export - - if (is_a($c, 'PEAR_Error')) { - Horde::logMessage("SyncML: refresh failed to export guid $guid:\n" . print_r($c, true), - __FILE__, __LINE__, PEAR_LOG_WARNING); - $state->log("Server-ExportFailed"); - continue; - } - - $size = strlen($c); - // return if we have to much data - if ($maxMsgSize && !$deviceInfo['supportLargeObjs']) { - if (($size + MIN_MSG_LEFT * 2) > $maxMsgSize) { - Horde::logMessage("SyncML: refresh failed to export guid $guid due to size $size", - __FILE__, __LINE__, PEAR_LOG_ERROR); - $state->log("Server-ExportFailed"); - continue; - } - if (($currentSize + $size + MIN_MSG_LEFT * 2) > $maxMsgSize) { - // put the item back in the queue - $adds[] = $guid; - $state->setSyncStatus(SERVER_SYNC_DATA_PENDING); - return $currentCmdID; - } - } - - Horde::logMessage("SyncML: refresh add $guid to client\n$c", - __FILE__, __LINE__, PEAR_LOG_DEBUG); - $cmd = new Horde_SyncML_Command_Sync_ContentSyncElement(); - - $cmd->setContent($c); - - $cmd->setContentType($contentType['ContentType']); - if (isset($contentType['ContentFormat'])) { - $cmd->setContentFormat($contentType['ContentFormat']); - } - - $cmd->setGUID($guid); - - $currentCmdID = $cmd->outputCommand($currentCmdID, $output, 'Add'); - $state->log('Server-Add'); - - // moreData split; put the guid back in the list and return - if ($cmd->hasMoreData()) { - $state->curSyncItem = &$cmd; - $state->setSyncStatus(SERVER_SYNC_DATA_PENDING); - return $currentCmdID; - } - $state->incNumberOfElements(); - } - } - - Horde::logMessage("SyncML: All items handled for sync $syncType", - __FILE__, __LINE__, PEAR_LOG_DEBUG); - - $state->removeExpiredUID($syncType, $serverAnchorNext); - $state->clearSync($syncType); - - return $currentCmdID; - } - - function loadData() { - global $registry; - - $state = &$_SESSION['SyncML.state']; - $syncType = $this->_targetLocURI; - $hordeType = $state->getHordeType($syncType); - $state->setTargetURI($syncType); - $future = $state->getServerAnchorNext($syncType); - $delta_add = 0; - - Horde::logMessage("SyncML: reading added items from database for $hordeType", - __FILE__, __LINE__, PEAR_LOG_DEBUG); - /* The items, which now match the filter criteria are show here, too - $state->setAddedItems($syncType, $registry->call($hordeType. '/listBy', - array('action' => 'add', - 'timestamp' => $future, - 'type' => $syncType, - 'filter' => $this->_filterExpression))); - $delta_add = count($state->getAddedItems($hordeType)); - */ - $state->mergeAddedItems($syncType, $registry->call($hordeType. '/list',array('filter' => $this->_filterExpression))); - - $this->_syncDataLoaded = TRUE; - - return count($state->getAddedItems($syncType)) - $delta_add; - } -} diff --git a/phpgwapi/inc/horde/Horde/SyncML/Sync/SlowSync.php b/phpgwapi/inc/horde/Horde/SyncML/Sync/SlowSync.php deleted file mode 100644 index 4f7ecb0749..0000000000 --- a/phpgwapi/inc/horde/Horde/SyncML/Sync/SlowSync.php +++ /dev/null @@ -1,314 +0,0 @@ - - * @author Joerg Lehrke - * @copyright (c) The Horde Project (http://www.horde.org/) - * @version $Id$ - */ -include_once 'Horde/SyncML/Sync/TwoWaySync.php'; - -class Horde_SyncML_Sync_SlowSync extends Horde_SyncML_Sync_TwoWaySync { - - function handleSync($currentCmdID, $hordeType, $syncType, &$output, $refts) { - global $registry; - - $history = $GLOBALS['egw']->contenthistory; - $state = &$_SESSION['SyncML.state']; - $maxMsgSize = $state->getMaxMsgSizeClient(); - $deviceInfo = $state->getClientDeviceInfo(); - - if (isset($deviceInfo['maxEntries'])) { - $maxEntries = $deviceInfo['maxEntries']; - if (!$maxMsgSize && !$maxEntries) { - // fallback to default - $maxEntries = MAX_ENTRIES; - } - } else { - $maxEntries = MAX_ENTRIES; - } - - $serverAnchorNext = $state->getServerAnchorNext($syncType); - - // now we remove all UID from contentmap that have not been verified in this slowsync - $state->removeOldUID($syncType, $serverAnchorNext); - - if (isset($state->curSyncItem)) { - // Finish the pending sync item - $cmd = &$state->curSyncItem; - if (!is_a($cmd, 'Horde_SyncML_Command_Sync_ContentSyncElement')) { - // Conflict with other datastore - Horde :: logMessage("SyncML: handleSync($currentCmdID, $hordeType, $syncType) moreData conflict found", - __FILE__, __LINE__, PEAR_LOG_WARNING); - $state->setSyncStatus(SERVER_SYNC_DATA_PENDING); - return $currentCmdID; - } - unset($state->curSyncItem); - $currentCmdID = $cmd->outputCommand($currentCmdID, $output, 'Sync'); - - // moreData split; save in session state and end current message - if ($cmd->hasMoreData()) { - $state->curSyncItem = &$cmd; - $state->setSyncStatus(SERVER_SYNC_DATA_PENDING); - return $currentCmdID; - } - $state->incNumberOfElements(); - } - - $adds =& $state->getAddedItems($syncType); - $conflicts =& $state->getConflictItems($syncType); - Horde::logMessage('SyncML: ' .count($adds). ' added items found for ' .$syncType, __FILE__, __LINE__, PEAR_LOG_DEBUG); - Horde::logMessage('SyncML: ' . count($conflicts) . ' items to delete on client found for ' . $syncType, __FILE__, __LINE__, PEAR_LOG_DEBUG); - - if (is_array($adds)) { - while ($guid = array_shift($adds)) { - $currentSize = $output->getOutputSize(); - // return if we have to much data - if (($maxEntries && ($state->getNumberOfElements() >= $maxEntries) - && isset($contentType['mayFragment']) - && $contentType['mayFragment']) || - ($maxMsgSize && (($currentSize + MIN_MSG_LEFT * 2) > $maxMsgSize))) { - // put the item back in the queue - $adds[] = $guid; - $state->maxNumberOfElements(); - $state->setSyncStatus(SERVER_SYNC_DATA_PENDING); - return $currentCmdID; - } - - if (($locID = $state->getLocID($syncType, $guid))) { - Horde::logMessage("SyncML: slowsync add to client: $guid ignored, already at client($locID)", - __FILE__, __LINE__, PEAR_LOG_DEBUG); - continue; - } - - $guid_ts = $state->getSyncTSforAction($guid, 'add'); - if ($guid_ts > $serverAnchorNext) { - // Change was made after we started this sync. - // Don't sent this now to the client. - Horde::logMessage("SyncML: slowsync add $guid is in our future", - __FILE__, __LINE__, PEAR_LOG_DEBUG); - continue; - } - - $contentType = $state->getPreferedContentTypeClient($this->_sourceLocURI, $this->_targetLocURI); - $c = $registry->call($hordeType . '/export', array('guid' => $guid, 'contentType' => $contentType)); - - if ($c === false) continue; // no content to export - - if (is_a($c, 'PEAR_Error')) { - Horde::logMessage("SyncML: slowsync failed to export guid $guid:\n" . print_r($c, true), - __FILE__, __LINE__, PEAR_LOG_WARNING); - continue; - } - - $size = strlen($c); - // return if we have to much data - if ($maxMsgSize && !$deviceInfo['supportLargeObjs']) { - if (($size + MIN_MSG_LEFT * 2) > $maxMsgSize) { - Horde::logMessage("SyncML: slowsync failed to export guid $guid due to size $size", - __FILE__, __LINE__, PEAR_LOG_ERROR); - continue; - } - if (($currentSize + $size + MIN_MSG_LEFT * 2) > $maxMsgSize) { - // put the item back in the queue - $adds[] = $guid; - $state->setSyncStatus(SERVER_SYNC_DATA_PENDING); - return $currentCmdID; - } - } - - Horde::logMessage("SyncML: slowsync add guid $guid to client\n$c", - __FILE__, __LINE__, PEAR_LOG_DEBUG); - $cmd = new Horde_SyncML_Command_Sync_ContentSyncElement(); - $cmd->setContent($c); - $cmd->setContentType($contentType['ContentType']); - if (isset($contentType['ContentFormat'])) { - $cmd->setContentFormat($contentType['ContentFormat']); - } - $cmd->setGUID($guid); - $currentCmdID = $cmd->outputCommand($currentCmdID, $output, 'Add'); - $state->log('Server-Add'); - - // moreData split; save in session state and end current message - if ($cmd->hasMoreData()) { - $state->curSyncItem = &$cmd; - $state->setSyncStatus(SERVER_SYNC_DATA_PENDING); - return $currentCmdID; - } - $state->incNumberOfElements(); - } - } - // handle remote deletes due to conflicts - if (count($conflicts) > 0) { - while ($locid = array_shift($conflicts)) { - $currentSize = $output->getOutputSize(); - // return if we have to much data - if (($maxEntries && ($state->getNumberOfElements() >= $maxEntries) - && isset ($contentType['mayFragment']) - && $contentType['mayFragment']) - || ($maxMsgSize - && (($currentSize +MIN_MSG_LEFT * 2) > $maxMsgSize))) { - // put the item back in the queue - $conflicts[] = $locid; - $state->maxNumberOfElements(); - $state->setSyncStatus(SERVER_SYNC_DATA_PENDING); - return $currentCmdID; - } - Horde :: logMessage("SyncML: delete client locid: $locid", - __FILE__, __LINE__, PEAR_LOG_DEBUG); - // Create a Delete request for client. - $cmd = new Horde_SyncML_Command_Sync_ContentSyncElement(); - $cmd->setLocURI($locid); - $currentCmdID = $cmd->outputCommand($currentCmdID, $output, 'Delete'); - $state->log('Server-DeletedConflicts'); - $state->removeUID($syncType, $locid); - - // moreData split; save in session state and end current message - if ($cmd->hasMoreData()) { - $state->curSyncItem = & $cmd; - $state->setSyncStatus(SERVER_SYNC_DATA_PENDING); - return $currentCmdID; - } - $state->incNumberOfElements(); - } - } - Horde::logMessage("SyncML: All items handled for sync $syncType", - __FILE__, __LINE__, PEAR_LOG_DEBUG); - - $state->removeExpiredUID($syncType, $serverAnchorNext); - $state->clearSync($syncType); - - return $currentCmdID; - } - - /** - * Here's where the actual processing of a client-sent Sync - * Command takes place. Entries are added or replaced - * from the server database by using Horde API (Registry) calls. - */ - function runSyncCommand(&$command) { - global $registry; - $history = $GLOBALS['egw']->contenthistory; - $state = &$_SESSION['SyncML.state']; - - $type = $this->_targetLocURI; - - $syncml_prefs = $GLOBALS['egw_info']['user']['preferences']['syncml']; - if (isset($syncml_prefs[$type])) { - $sync_conflicts = $syncml_prefs[$type]; - } else { - $sync_conflicts = CONFLICT_SERVER_WINNING; - } - - $hordeType = $state->getHordeType($type); - - $syncElementItems = $command->getSyncElementItems(); - - foreach($syncElementItems as $syncItem) { - - if(!$contentType = $syncItem->getContentType()) { - $contentType = $state->getPreferedContentType($type); - } - - if (($contentType == 'text/x-vcalendar' || $contentType == 'text/calendar') - && strpos($syncItem->getContent(), 'BEGIN:VTODO') !== false) { - $hordeType = 'tasks'; - } - - $guid = false; - $locURI = $syncItem->getLocURI(); - - $oguid = $state->getGlobalUID($type, $locURI); - - $guid = $registry->call($hordeType . '/search', - array($state->convertClient2Server($syncItem->getContent(), $contentType), $contentType, $oguid, $type)); - - if (!is_a($guid, 'PEAR_Error') && $guid) { - // Check if the found entry came from the client - $guid_ts = $state->getSyncTSforAction($guid, 'add'); - $sync_ts = $state->getChangeTS($type, $guid); - if ($oguid != $guid && $sync_ts && $sync_ts == $guid_ts) { - // Entry came from the client, so we get a duplicate here - Horde::logMessage('SyncML: CONFLICT for locuri ' . $syncItem->getLocURI() - . ' guid ' . $guid , __FILE__, __LINE__, PEAR_LOG_WARNING); - if ($sync_conflicts != CONFLICT_RESOLVED_WITH_DUPLICATE) { - $state->log("Client-AddReplaceIgnored"); - $command->setStatus(RESPONSE_CONFILCT_RESOLVED_WITH_DUPLICATE); - continue; - } - } else { - # Entry exists in database already. Just update the mapping - Horde::logMessage("SyncML: adding mapping for locuri: $locURI and guid: $guid", - __FILE__, __LINE__, PEAR_LOG_DEBUG); - $state->setUID($type, $locURI, $guid); - $state->log("Client-Map"); - $command->setStatus(RESPONSE_ALREADY_EXISITS); - continue; - } - } - if ($sync_conflicts > CONFLICT_RESOLVED_WITH_DUPLICATE) { - // We enforce the client not to change anything - if ($sync_conflicts > CONFLICT_CLIENT_CHANGES_IGNORED) { - // delete this item from client - Horde::logMessage("SyncML: Server RO! REMOVE $locURI from client", - __FILE__, __LINE__, PEAR_LOG_WARNING); - $state->addConflictItem($type, $locURI); - } else { - Horde::logMessage('SyncML: Server RO! REJECT all client changes', - __FILE__, __LINE__, PEAR_LOG_WARNING); - $state->log("Client-AddReplaceIgnored"); - } - $command->setStatus(RESPONSE_NO_EXECUTED); - continue; - } - - // Add entry to the database. - $state->removeUID($type, $locURI); - Horde::logMessage("SyncML: try to add $locURI with contentype $contentType to $hordeType", - __FILE__, __LINE__, PEAR_LOG_DEBUG); - $guid = $registry->call($hordeType . '/import', - array($state->convertClient2Server($syncItem->getContent(), $contentType), $contentType)); - if (!is_a($guid, 'PEAR_Error') && $guid) { - // first we try the modification timestamp then the creation ts - if (!($ts = $state->getSyncTSforAction($guid, 'modify'))) { - $ts = $state->getSyncTSforAction($guid, 'add'); - } - $state->setUID($type, $locURI, $guid, $ts); - $state->log("Client-AddReplace"); - Horde::logMessage("SyncML: replaced/added client entry $locURI as $guid", - __FILE__, __LINE__, PEAR_LOG_DEBUG); - } else { - Horde::logMessage('SyncML: Error in replacing/add client entry ' . $locURI . ': '. $guid->message, - __FILE__, __LINE__, PEAR_LOG_ERR); - $state->log("Client-AddFailure"); - } - } - } - - function loadData() { - global $registry; - - $state = &$_SESSION['SyncML.state']; - $syncType = $this->_targetLocURI; - $hordeType = $state->getHordeType($syncType); - $state->setTargetURI($syncType); - $future = $state->getServerAnchorNext($syncType); - - $state->mergeAddedItems($syncType, $registry->call($hordeType. '/list', array('filter' => $this->_filterExpression))); - - $this->_syncDataLoaded = TRUE; - - return count($state->getAddedItems($syncType)) + count($state->getConflictItems($syncType)); - } -} diff --git a/phpgwapi/inc/horde/Horde/SyncML/Sync/TwoWaySync.php b/phpgwapi/inc/horde/Horde/SyncML/Sync/TwoWaySync.php deleted file mode 100644 index e26baae63e..0000000000 --- a/phpgwapi/inc/horde/Horde/SyncML/Sync/TwoWaySync.php +++ /dev/null @@ -1,460 +0,0 @@ - - * @author Karsten Fourmont - * @author Joerg Lehrke - * @copyright (c) The Horde Project (http://www.horde.org/) - * @version $Id$ - */ -include_once 'Horde/SyncML/Sync.php'; -include_once 'Horde/SyncML/Command/Sync/ContentSyncElement.php'; - -class Horde_SyncML_Sync_TwoWaySync extends Horde_SyncML_Sync { - - function endSync($currentCmdID, & $output) { - global $registry; - - $state = & $_SESSION['SyncML.state']; - - $syncType = $this->_targetLocURI; - - $hordeType = $state->getHordeType($syncType); - - $refts = $state->getServerAnchorLast($syncType); - $currentCmdID = $this->handleSync($currentCmdID, $hordeType, $syncType, $output, $refts); - - return $currentCmdID; - } - - function handleSync($currentCmdID, $hordeType, $syncType, & $output, $refts) { - global $registry; - - // array of Items which got modified, but got never send to the client before - $missedAdds = array (); - - $history = $GLOBALS['egw']->contenthistory; - $state = & $_SESSION['SyncML.state']; - $maxMsgSize = $state->getMaxMsgSizeClient(); - $deviceInfo = $state->getClientDeviceInfo(); - - if (isset($deviceInfo['maxEntries'])) { - $maxEntries = $deviceInfo['maxEntries']; - if (!$maxMsgSize && !$maxEntries) { - // fallback to default - $maxEntries = MAX_ENTRIES; - } - } else { - $maxEntries = MAX_ENTRIES; - } - - $serverAnchorNext = $state->getServerAnchorNext($syncType); - - - if (isset ($state->curSyncItem)) { - // Finish the pending sync item - $cmd = & $state->curSyncItem; - if (!is_a($cmd, 'Horde_SyncML_Command_Sync_ContentSyncElement')) { - // Conflict with other datastore - Horde :: logMessage("SyncML: handleSync($currentCmdID, $hordeType, $syncType) moreData conflict found", - __FILE__, __LINE__, PEAR_LOG_WARNING); - $state->setSyncStatus(SERVER_SYNC_DATA_PENDING); - return $currentCmdID; - } - unset ($state->curSyncItem); - $currentCmdID = $cmd->outputCommand($currentCmdID, $output, 'Sync'); - - // moreData split; save in session state and end current message - if ($cmd->hasMoreData()) { - $state->curSyncItem = & $cmd; - $state->setSyncStatus(SERVER_SYNC_DATA_PENDING); - return $currentCmdID; - } - $state->incNumberOfElements(); - } - - $changes =& $state->getChangedItems($syncType); - $deletes =& $state->getDeletedItems($syncType); - $adds =& $state->getAddedItems($syncType); - $conflicts =& $state->getConflictItems($syncType); - - Horde::logMessage('SyncML: ' . count($changes) . ' changed items found for ' . $syncType, __FILE__, __LINE__, PEAR_LOG_DEBUG); - Horde::logMessage('SyncML: ' . count($deletes) . ' deleted items found for ' . $syncType, __FILE__, __LINE__, PEAR_LOG_DEBUG); - Horde::logMessage('SyncML: ' . count($conflicts) . ' items to delete on client found for ' . $syncType, __FILE__, __LINE__, PEAR_LOG_DEBUG); - Horde::logMessage('SyncML: ' . count($adds) . ' added items found for ' . $syncType, __FILE__, __LINE__, PEAR_LOG_DEBUG); - - // handle changes - if (is_array($changes)) { - while ($guid = array_shift($changes)) { - $currentSize = $output->getOutputSize(); - // return if we have to much data - if (($maxEntries - && ($state->getNumberOfElements() >= $maxEntries) - && isset ($contentType['mayFragment']) - && $contentType['mayFragment']) - || ($maxMsgSize - && (($currentSize +MIN_MSG_LEFT * 2) > $maxMsgSize))) { - // put the item back in the queue - $changes[] = $guid; - $state->maxNumberOfElements(); - $state->setSyncStatus(SERVER_SYNC_DATA_PENDING); - return $currentCmdID; - } - - $guid_ts = $state->getSyncTSforAction($guid, 'modify'); - $sync_ts = $state->getChangeTS($syncType, $guid); - Horde :: logMessage("SyncML: timestamp modify $guid guid_ts: $guid_ts sync_ts: $sync_ts", - __FILE__, __LINE__, PEAR_LOG_DEBUG); - if ($sync_ts && $sync_ts == $guid_ts) { - // Change was done by us upon request of client. - // Don't mirror that back to the client. - Horde :: logMessage("SyncML: change: $guid ignored, came from client", - __FILE__, __LINE__, PEAR_LOG_DEBUG); - continue; - } - if ($guid_ts > $serverAnchorNext) { - // Change was made after we started this sync. - // Don't sent this now to the client. - Horde :: logMessage("SyncML: change $guid is in our future: $serverAnchorNext", - __FILE__, __LINE__, PEAR_LOG_DEBUG); - continue; - } - $locid = $state->getLocID($syncType, $guid); - if (!$locid) { - // somehow we missed to add, lets store the uid, so we add this entry later - $missedAdds[] = $guid; - Horde :: logMessage("SyncML: unable to create change for $guid: locid not found in map", - __FILE__, __LINE__, PEAR_LOG_WARNING); - continue; - } - - // Create a replace request for client. - $contentType = $state->getPreferedContentTypeClient($this->_sourceLocURI, $this->_targetLocURI); - $c = $registry->call($hordeType . '/export', array ( - 'guid' => $guid, - 'contentType' => $contentType - )); - - if ($c === false) continue; // no content to export - - if (is_a($c, 'PEAR_Error')) { - // Item in history but not in database. Strange, but can happen. - Horde :: logMessage("SyncML: change: export of guid $guid failed:\n" . print_r($c, true), - __FILE__, __LINE__, PEAR_LOG_WARNING); - continue; - } - - $size = strlen($c); - // return if we have to much data - if ($maxMsgSize && !$deviceInfo['supportLargeObjs']) { - if (($size + MIN_MSG_LEFT * 2) > $maxMsgSize) { - Horde :: logMessage("SyncML: change: export of guid $guid failed due to size $size", - __FILE__, __LINE__, PEAR_LOG_ERROR); - $state->log('Server-ExportFailed'); - continue; - } - if (($currentSize + $size + MIN_MSG_LEFT * 2) > $maxMsgSize) { - // put the item back in the queue - $changes[] = $guid; - $state->setSyncStatus(SERVER_SYNC_DATA_PENDING); - return $currentCmdID; - } - } - - Horde :: logMessage("SyncML: change: export guid $guid, content:\n$c", - __FILE__, __LINE__, PEAR_LOG_DEBUG); - $cmd = new Horde_SyncML_Command_Sync_ContentSyncElement(); - # LK $cmd->setContent($state->convertServer2Client($c, $contentType)); - $cmd->setContent($c); - $cmd->setLocURI($locid); - $cmd->setContentType($contentType['ContentType']); - if (isset ($contentType['ContentFormat'])) { - $cmd->setContentFormat($contentType['ContentFormat']); - } - $currentCmdID = $cmd->outputCommand($currentCmdID, $output, 'Replace'); - $state->log('Server-Replace'); - - // moreData split; save in session state and end current message - if ($cmd->hasMoreData()) { - $state->curSyncItem = & $cmd; - $state->setSyncStatus(SERVER_SYNC_DATA_PENDING); - return $currentCmdID; - } - $state->incNumberOfElements(); - } - } - Horde :: logMessage("SyncML: handling sync (changes done) " . $currentCmdID, - __FILE__, __LINE__, PEAR_LOG_DEBUG); - - // handle deletes - if (is_array($deletes)) { - while ($guid = array_shift($deletes)) { - $currentSize = $output->getOutputSize(); - // return if we have to much data - if (($maxEntries && ($state->getNumberOfElements() >= $maxEntries) - && isset ($contentType['mayFragment']) - && $contentType['mayFragment']) - || ($maxMsgSize - && (($currentSize + MIN_MSG_LEFT * 2) > $maxMsgSize))) { - // put the item back in the queue - $deletes[] = $guid; - $state->maxNumberOfElements(); - $state->setSyncStatus(SERVER_SYNC_DATA_PENDING); - return $currentCmdID; - } - - $guid_ts = $state->getSyncTSforAction($guid, 'delete'); - $sync_ts = $state->getChangeTS($syncType, $guid); - Horde :: logMessage("SyncML: timestamp delete guid_ts: $guid_ts sync_ts: $sync_ts", - __FILE__, __LINE__, PEAR_LOG_DEBUG); - if ($sync_ts && $sync_ts == $guid_ts) { - // Change was done by us upon request of client. - // Don't mirror that back to the client. - Horde :: logMessage("SyncML: delete $guid ignored, came from client", - __FILE__, __LINE__, PEAR_LOG_DEBUG); - if ($sync_ts < $serverAnchorNext - && ($locid = $state->getLocID($syncType, $guid))) { - // Now we can remove the past - $state->removeUID($syncType, $locid); - } - continue; - } - if ($guid_ts > $serverAnchorNext) { - // Change was made after we started this sync. - // Don't sent this now to the client. - Horde :: logMessage("SyncML: delete $guid is in our future: $serverAnchorNext", __FILE__, __LINE__, PEAR_LOG_DEBUG); - continue; - } - $locid = $state->getLocID($syncType, $guid); - if (!$locid) { - Horde :: logMessage("SyncML: unable to delete $guid: locid not found in map", __FILE__, __LINE__, PEAR_LOG_INFO); - $state->log("Server-DeleteFailure"); - continue; - } - - Horde :: logMessage("SyncML: delete: $guid", __FILE__, __LINE__, PEAR_LOG_DEBUG); - // Create a Delete request for client. - $cmd = new Horde_SyncML_Command_Sync_ContentSyncElement(); - $cmd->setLocURI($locid); - $currentCmdID = $cmd->outputCommand($currentCmdID, $output, 'Delete'); - $state->log('Server-Delete'); - $state->removeUID($syncType, $locid); - - // moreData split; save in session state and end current message - if ($cmd->hasMoreData()) { - $state->curSyncItem = & $cmd; - $state->setSyncStatus(SERVER_SYNC_DATA_PENDING); - return $currentCmdID; - } - $state->incNumberOfElements(); - } - } - - // handle remote deletes due to conflicts - if (count($conflicts) > 0) { - while ($locid = array_shift($conflicts)) { - $currentSize = $output->getOutputSize(); - // return if we have to much data - if (($maxEntries && ($state->getNumberOfElements() >= $maxEntries) - && isset ($contentType['mayFragment']) - && $contentType['mayFragment']) - || ($maxMsgSize - && (($currentSize +MIN_MSG_LEFT * 2) > $maxMsgSize))) { - // put the item back in the queue - $conflicts[] = $locid; - $state->maxNumberOfElements(); - $state->setSyncStatus(SERVER_SYNC_DATA_PENDING); - return $currentCmdID; - } - Horde :: logMessage("SyncML: delete client locid: $locid", __FILE__, __LINE__, PEAR_LOG_DEBUG); - // Create a Delete request for client. - $cmd = new Horde_SyncML_Command_Sync_ContentSyncElement(); - $cmd->setLocURI($locid); - $currentCmdID = $cmd->outputCommand($currentCmdID, $output, 'Delete'); - $state->log('Server-DeletedConflicts'); - $state->removeUID($syncType, $locid); - - // moreData split; save in session state and end current message - if ($cmd->hasMoreData()) { - $state->curSyncItem = & $cmd; - $state->setSyncStatus(SERVER_SYNC_DATA_PENDING); - return $currentCmdID; - } - $state->incNumberOfElements(); - } - } - // Horde::logMessage("SyncML: handling sync ".$currentCmdID, __FILE__, __LINE__, PEAR_LOG_DEBUG); - - // handle missing adds. - if (count($missedAdds) > 0) { - Horde :: logMessage("SyncML: add missed changes as adds " . count($adds) . ' / ' . $missedAdds[0], - __FILE__, __LINE__, PEAR_LOG_DEBUG); - $adds = array_merge($adds, $missedAdds); - Horde :: logMessage("SyncML: merged adds counter " . count($adds) . ' / ' . $adds[0], - __FILE__, __LINE__, PEAR_LOG_DEBUG); - } - - if (is_array($adds)) { - while ($guid = array_shift($adds)) { - $currentSize = $output->getOutputSize(); - // return if we have to much data - if (($maxEntries && ($state->getNumberOfElements() >= $maxEntries) - && isset ($contentType['mayFragment']) - && $contentType['mayFragment']) - || ($maxMsgSize - && (($currentSize +MIN_MSG_LEFT * 2) > $maxMsgSize))) { - // put the item back in the queue - $adds[] = $guid; - $state->maxNumberOfElements(); - $state->setSyncStatus(SERVER_SYNC_DATA_PENDING); - return $currentCmdID; - } - - // first we try the modification timestamp then the creation ts - if (!($guid_ts = $state->getSyncTSforAction($guid, 'modify'))) { - $guid_ts = $state->getSyncTSforAction($guid, 'add'); - } - - $sync_ts = $state->getChangeTS($syncType, $guid); - Horde :: logMessage("SyncML: timestamp add $guid guid_ts: $guid_ts sync_ts: $sync_ts", __FILE__, __LINE__, PEAR_LOG_DEBUG); - if ($sync_ts && $sync_ts == $guid_ts) { - // Change was done by us upon request of client. - // Don't mirror that back to the client. - Horde :: logMessage("SyncML: add: $guid ignored, came from client", - __FILE__, __LINE__, PEAR_LOG_DEBUG); - continue; - } - if ($guid_ts > $serverAnchorNext && !in_array($guid, $conflicts)) { - // Change was made after we started this sync. - // Don't sent this now to the client. - Horde :: logMessage("SyncML: add $guid is in our future: $serverAnchorNext", - __FILE__, __LINE__, PEAR_LOG_DEBUG); - continue; - } - - $locid = $state->getLocID($syncType, $guid); - - if ($locid && $refts == 0) { - // For slow sync (ts=0): do not add data for which we - // have a locid again. This is a heuristic to avoid - // duplication of entries. - Horde :: logMessage("SyncML: skipping add of guid $guid as there already is a locid $locid", __FILE__, __LINE__, PEAR_LOG_DEBUG); - continue; - } - Horde :: logMessage("SyncML: add: $guid", __FILE__, __LINE__, PEAR_LOG_DEBUG); - - // Create an Add request for client. - $contentType = $state->getPreferedContentTypeClient($this->_sourceLocURI, $this->_targetLocURI); - $c = $registry->call($hordeType . '/export', array ( - 'guid' => $guid, - 'contentType' => $contentType, - - )); - - if ($c === false) continue; // no content to export - - if (is_a($c, 'PEAR_Error')) { - // Item in history but not in database. Strange, but can happen. - Horde :: logMessage("SyncML: add: export of guid $guid failed:\n" . print_r($c, true), - __FILE__, __LINE__, PEAR_LOG_WARNING); - continue; - } - - $size = strlen($c); - // return if we have to much data - if ($maxMsgSize && !$deviceInfo['supportLargeObjs']) { - if (($size +MIN_MSG_LEFT * 2) > $maxMsgSize) { - Horde :: logMessage("SyncML: add: export of guid $guid failed due to size $size", __FILE__, __LINE__, PEAR_LOG_ERROR); - $state->log("Server-ExportFailed"); - continue; - } - if (($currentSize + $size +MIN_MSG_LEFT * 2) > $maxMsgSize) { - // put the item back in the queue - $adds[] = $guid; - $state->setSyncStatus(SERVER_SYNC_DATA_PENDING); - return $currentCmdID; - } - } - - Horde :: logMessage("SyncML: add guid $guid to client\n$c", - __FILE__, __LINE__, PEAR_LOG_DEBUG); - $cmd = new Horde_SyncML_Command_Sync_ContentSyncElement(); - $cmd->setContent($c); - $cmd->setContentType($contentType['ContentType']); - if (isset ($contentType['ContentFormat'])) { - $cmd->setContentFormat($contentType['ContentFormat']); - } - $cmd->setGUID($guid); - $currentCmdID = $cmd->outputCommand($currentCmdID, $output, 'Add'); - $state->log('Server-Add'); - - // moreData split; put the guid back in the list and return - if ($cmd->hasMoreData()) { - $state->curSyncItem = & $cmd; - $state->setSyncStatus(SERVER_SYNC_DATA_PENDING); - return $currentCmdID; - } - $state->incNumberOfElements(); - } - } - Horde::logMessage("SyncML: All items handled for sync $syncType", - __FILE__, __LINE__, PEAR_LOG_DEBUG); - - $state->removeExpiredUID($syncType, time()); - $state->clearSync($syncType); - - return $currentCmdID; - } - - function loadData() { - global $registry; - - $state =& $_SESSION['SyncML.state']; - $syncType = $this->_targetLocURI; - $hordeType = $state->getHordeType($syncType); - $refts = $state->getServerAnchorLast($syncType); - $future = $state->getServerAnchorNext($syncType); - - $addedItems =& $registry->call($hordeType . '/listBy', array ( - 'action' => 'add', - 'timestamp' => $refts, - 'type' => $syncType, - 'filter' => $this->_filterExpression - )); - - $state->setAddedItems($syncType, $addedItems); - - $changedItems =& $state->getChangedItems($syncType); - - $deletedItems =& $registry->call($hordeType . '/listBy', array ( - 'action' => 'delete', - 'timestamp' => $refts, - 'type' => $syncType, - 'filter' => $this->_filterExpression - )); - foreach ($deletedItems as $guid) - { - if (strstr($guid, ':')) - { - $parentGUID = array_shift(explode(':', $guid)); - if (!in_array($parentGUID, $changedItems)) - { - $changedItems[] = $parentGUID; - } - } - } - $state->setDeletedItems($syncType, $deletedItems); - - $this->_syncDataLoaded = true; - - return count($changedItems) + count($deletedItems) + count($addedItems) + count($state->getConflictItems($syncType)); - } -} \ No newline at end of file diff --git a/phpgwapi/inc/horde/Horde/Util.php b/phpgwapi/inc/horde/Horde/Util.php deleted file mode 100644 index 1380dc0aea..0000000000 --- a/phpgwapi/inc/horde/Horde/Util.php +++ /dev/null @@ -1,836 +0,0 @@ - - * Copyright 1999-2005 Jon Parise - * - * 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 - * @author Jon Parise - * @since Horde 3.0 - * @package Horde_Util - */ -class Util { - - /** - * Returns an object's clone. - * - * @param object &$obj The object to clone. - * - * @return object The cloned object. - */ - function &cloneObject(&$obj) - { - if (version_compare(zend_version(), '2', '>')) { - return clone($obj); - } else { - $newObj = $obj; - return $newObj; - } - } - - /** - * 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. - * - * @access public - * - * @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. - */ - function bufferOutput() - { - if (func_num_args() == 0) { - return false; - } - $eval = 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')) { - $eval = true; - } elseif (!function_exists($function) && - ($function != 'eval')) { - return false; - } - - ob_start(); - if ($eval) { - eval($function . " '" . implode(',', $args) . "';"); - } elseif ($function == 'eval') { - eval($args[0]); - } else { - call_user_func_array($function, $args); - } - $output = ob_get_contents(); - ob_end_clean(); - - return $output; - } - - /** - * 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. - * - * @access public - * - * @param string $varname The variable name to check. - * - * @return mixed Null if the var is in user input, the variable value - * otherwise. - */ - function nonInputVar($varname) - { - if (isset($_GET[$varname]) || - isset($_POST[$varname]) || - isset($_COOKIE[$varname])) { - return null; - } else { - return isset($GLOBALS[$varname]) ? $GLOBALS[$varname] : null; - } - } - - /** - * 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. - * - * @access public - * - * @param string $url The URL to modify - * @param mixed $parameter Either the name=value pair to add - * (DEPRECATED) -or- - * 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 If true, and we don't have argument separators - * yet, the argument separator gets encoded. - * - * @return string The modified URL. - * - * @since Horde 2.1 - */ - function addParameter($url, $parameter, $value = null, $encode = true) - { - if (empty($parameter)) { - return $url; - } - - if (!is_array($parameter)) { - /* This is deprecated should be removed in the future. */ - if (is_null($value)) { - @list($parameter, $value) = explode('=', $parameter, 2); - } - $add = array($parameter => $value); - } else { - $add = $parameter; - } - - $arg = $encode ? '&' : '&'; - if (($pos = strpos($url, '?')) === false) { - $glue = '?'; - } else { - /* Check if the argument separator has been already - * htmlentities-ized in the URL. */ - $query = substr($url, $pos + 1); - if (preg_match('/=.*?&.*?=/', $query)) { - $arg = '&'; - $query = strtr($query, array_flip(get_html_translation_table(HTML_ENTITIES))); - } elseif (preg_match('/=.*?&.*?=/', $query)) { - $arg = '&'; - } - $pairs = explode($arg, $query); - $params = array(); - foreach ($pairs as $pair) { - $pair = explode('=', $pair, 2); - $params[$pair[0]] = count($pair) == 2 ? $pair[1] : ''; - } - $glue = $arg; - } - - $url_params = array(); - foreach ($add as $parameter => $value) { - if (!isset($params[$parameter])) { - if (is_array($value)) { - foreach ($value as $val) { - $url_params[] = urlencode($parameter) . '[]=' . urlencode($val); - } - } else { - $url_params[] = urlencode($parameter) . '=' . urlencode($value); - } - } - } - - if (count($url_params)) { - return $url . $glue . implode($arg, $url_params); - } else { - return $url; - } - } - - /** - * Removes name=value pairs from a URL. - * - * @access public - * - * @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. - * - * @since Horde 2.2 - */ - 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 = strtr($query, array_flip(get_html_translation_table(HTML_ENTITIES))); - } - - /* 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. - * - * @access public - * - * @param string $url The URL to modify. - * - * @return string The requested URI. - */ - function nocacheUrl($url) - { - static $rand_num; - - require_once 'Horde/Browser.php'; - $browser = &Browser::singleton(); - - /* We may need to set a dummy parameter 'nocache' since some - * browsers do not always honor the 'no-cache' header. */ - if ($browser->hasQuirk('cache_same_url')) { - if (!isset($rand_num)) { - $rand_num = base_convert(microtime(), 10, 36); - } - return Util::addParameter($url, 'nocache', $rand_num); - } else { - return $url; - } - } - - /** - * Returns a hidden form input containing the session name and id. - * - * @access public - * - * @param boolean $append_session 0 = only if needed, 1 = always. - * - * @return string The hidden form input, if needed/requested. - */ - function formInput($append_session = 0) - { - if ($append_session == 1 || - !isset($_COOKIE[session_name()])) { - return '\n"; - } else { - return ''; - } - } - - /** - * Prints a hidden form input containing the session name and id. - * - * @access public - * - * @param boolean $append_session 0 = only if needed, 1 = always. - */ - function pformInput($append_session = 0) - { - echo Util::formInput($append_session); - } - - /** - * If magic_quotes_gpc is in use, run stripslashes() on $var. - * - * @access public - * - * @param string &$var The string to un-quote, if necessary. - * - * @return string $var, minus any magic quotes. - */ - function dispelMagicQuotes(&$var) - { - static $magic_quotes; - - if (!isset($magic_quotes)) { - $magic_quotes = get_magic_quotes_gpc(); - } - - if ($magic_quotes) { - if (!is_array($var)) { - $var = stripslashes($var); - } else { - array_walk($var, array('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. - * - * @access public - * - * @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. - */ - function getFormData($var, $default = null) - { - return (($val = Util::getPost($var)) !== null) - ? $val : Util::getGet($var, $default); - } - - /** - * Gets a form variable from GET data, stripped of magic quotes if - * necessary. This function will NOT return a POST variable. - * - * @access public - * - * @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. - * - * @since Horde 2.2 - */ - function getGet($var, $default = null) - { - return (isset($_GET[$var])) - ? Util::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. - * - * @access public - * - * @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. - * - * @since Horde 2.2 - */ - function getPost($var, $default = null) - { - return (isset($_POST[$var])) - ? Util::dispelMagicQuotes($_POST[$var]) - : $default; - } - - /** - * Determines the location of the system temporary directory. - * - * @access public - * - * @return string A directory name which can be used for temp files. - * Returns false if one could not be found. - */ - 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. - */ - function getTempFile($prefix = '', $delete = true, $dir = '', $secure = false) - { - if (empty($dir) || !is_dir($dir)) { - $tmp_dir = Util::getTempDir(); - } else { - $tmp_dir = $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; - } else { - if ($delete) { - Util::deleteAtShutdown($tmp_file, true, $secure); - } - return $tmp_file; - } - } - - /** - * Creates a temporary directory in the system's temporary directory. - * - * @access public - * - * @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. - */ - function createTempDir($delete = true, $temp_dir = null) - { - if (is_null($temp_dir)) { - $temp_dir = Util::getTempDir(); - } - - if (empty($temp_dir)) { - return false; - } - - /* Get the first 8 characters of a random string to use as a temporary - directory name. */ - do { - $temp_dir .= '/' . substr(base_convert(mt_rand() . microtime(), 10, 36), 0, 8); - } while (file_exists($temp_dir)); - - $old_umask = umask(0000); - if (!mkdir($temp_dir, 0700)) { - $temp_dir = false; - } elseif ($delete) { - Util::deleteAtShutdown($temp_dir); - } - umask($old_umask); - - return $temp_dir; - } - - /** - * 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 Util::_deleteAtShutdown). - * - * The first time it is called, it initializes the array and registers - * Util::_deleteAtShutdown() as a shutdown function - no need to do so - * manually. - * - * The second parameter allows the unregistering of previously registered - * elements. - * - * @access public - * - * @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? - */ - function deleteAtShutdown($filename = false, $register = true, - $secure = false) - { - static $dirs, $files, $securedel; - - /* Initialization of variables and shutdown functions. */ - if (is_null($dirs)){ - $dirs = array(); - $files = array(); - $securedel = array(); - register_shutdown_function(array('Util', '_deleteAtShutdown')); - } - - if ($filename) { - if ($register) { - if (@is_dir($filename)) { - $dirs[$filename] = true; - } else { - $files[$filename] = true; - } - if ($secure) { - $securedel[$filename] = true; - } - } else { - unset($dirs[$filename]); - unset($files[$filename]); - unset($securedel[$filename]); - } - } else { - return array($dirs, $files, $securedel); - } - } - - /** - * Deletes registered files at request shutdown. - * - * This function should never be called manually; it is registered as a - * shutdown function by Util::deleteAtShutdown() and called automatically - * at the end of the request. It will retrieve the list of folders and - * files to delete from Util::deleteAtShutdown()'s static array, and then - * iterate through, deleting folders recursively. - * - * Contains code from gpg_functions.php. - * Copyright (c) 2002-2003 Braverock Ventures - * - * @access private - */ - function _deleteAtShutdown() - { - $registered = Util::deleteAtShutdown(); - $dirs = $registered[0]; - $files = $registered[1]; - $secure = $registered[2]; - - foreach ($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($secure[$file])) { - $random_str = ''; - for ($i = 0; $i < filesize($file); $i++) { - $random_str .= chr(mt_rand(0, 255)); - } - $fp = fopen($file, 'r+'); - fwrite($fp, $random_str); - fclose($fp); - } - @unlink($file); - } - } - - foreach ($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. - * - * @access public - * - * @param string $code Any addtional javascript code to run before - * closing the window. - */ - function closeWindowJS($code = '') - { - echo ''; - } - - /** - * Caches the result of extension_loaded() calls. - * - * @access private - * - * @param string $ext The extension name. - * - * @return boolean Is the extension loaded? - */ - function extensionExists($ext) - { - static $cache = array(); - - if (!isset($cache[$ext])) { - $cache[$ext] = extension_loaded($ext); - } - - return $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. - */ - function loadExtension($ext) - { - /* If $ext is already loaded, our work is done. */ - if (Util::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 (substr(PHP_OS, 0, 3) == 'WIN') { - $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. - */ - function assertDriverConfig($params, $fields, $name, $info = array()) - { - $info = array_merge($info, - array('params' => $params, - 'fields' => $fields, - 'name' => $name)); - - if (!is_array($params) || !count($params)) { - require_once 'PEAR.php'; - return PEAR::throwError(sprintf(_("No configuration information specified for %s."), $name), - HORDE_ERROR_DRIVER_CONFIG_MISSING, - $info); - } - - foreach ($fields as $field) { - if (!isset($params[$field])) { - require_once 'PEAR.php'; - return PEAR::throwError(sprintf(_("Required '%s' not specified in configuration."), $field, $name), - 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. - */ - function date2strftime($format) - { - $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', '%'); - $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', '%%'); - - $result = ''; - for ($pos = 0; $pos < strlen($format);) { - for ($symbol = 0; $symbol < count($dateSymbols); $symbol++) { - if (strpos($format, $dateSymbols[$symbol], $pos) === $pos) { - $result .= $strftimeSymbols[$symbol]; - $pos += strlen($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. - */ - function strftime2date($format) - { - $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', '%'); - $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', '%%'); - - return str_replace($strftimeSymbols, $dateSymbols, $format); - } - -} - -if (!function_exists('_')) { - function _($string) - { - return $string; - } - - function bindtextdomain() - { - } - - function textdomain() - { - } - - function dgettext($domain, $message) - { - return $message; - } - - function ngettext($singular, $plural, $number) - { - return $number > 1 ? $plural : $singular; - } -} diff --git a/phpgwapi/inc/horde/Horde/iCalendar.php b/phpgwapi/inc/horde/Horde/iCalendar.php deleted file mode 100644 index 6962bfeab8..0000000000 --- a/phpgwapi/inc/horde/Horde/iCalendar.php +++ /dev/null @@ -1,1708 +0,0 @@ - - * @author Joerg Lehrke - * @copyright (c) The Horde Project (http://www.horde.org/) - * @version $Id$ - */ - -/** - * Class representing iCalendar files. - */ -class Horde_iCalendar { - - /** - * The parent (containing) iCalendar object. - * - * @var Horde_iCalendar - */ - var $_container = false; - - /** - * The name/value pairs of attributes for this object (UID, - * DTSTART, etc.). Which are present depends on the object and on - * what kind of component it is. - * - * @var array - */ - var $_attributes = array(); - - /** - * Any children (contained) iCalendar components of this object. - * - * @var array - */ - var $_components = array(); - - /** - * According to RFC 2425, we should always use CRLF-terminated lines. - * - * @var string - */ - var $_newline = "\r\n"; - - /** - * iCalendar format version (different behavior for 1.0 and 2.0 - * especially with recurring events). - * - * @var string - */ - var $_version; - - function Horde_iCalendar($version = '2.0') - { - $this->_version = $version; - $this->setAttribute('VERSION', $version); - } - - /** - * Return a reference to a new component. - * - * @param string $type The type of component to return - * @param Horde_iCalendar $container A container that this component - * will be associated with. - * - * @return object Reference to a Horde_iCalendar_* object as specified. - * - * @static - */ - function &newComponent($type, &$container) - { - $type = String::lower($type); - $class = 'Horde_iCalendar_' . $type; - if (!class_exists($class)) { - // include relative from current dir, as we no longer set (old) Horde dir in include path - include 'iCalendar/' . $type . '.php'; - } - if (class_exists($class)) { - $component = new $class(); - if ($container !== false) { - $component->_container = &$container; - // Use version of container, not default set by component - // constructor. - $component->_version = $container->_version; - } - } else { - // Should return an dummy x-unknown type class here. - $component = false; - } - - return $component; - } - - /** - * Sets the value of an attribute. - * - * @param string $name The name of the attribute. - * @param string $value The value of the attribute. - * @param array $params Array containing any addition parameters for - * this attribute. - * @param boolean $append True to append the attribute, False to replace - * the first matching attribute found. - * @param array $values Array representation of $value. For - * comma/semicolon seperated lists of values. If - * not set use $value as single array element. - */ - function setAttribute($name, $value, $params = array(), $append = true, - $values = false) - { - // Make sure we update the internal format version if - // setAttribute('VERSION', ...) is called. - if ($name == 'VERSION') { - $this->_version = $value; - if ($this->_container !== false) { - $this->_container->_version = $value; - } - } - - if (!$values) { - $values = array($value); - } - $found = false; - if (!$append) { - foreach (array_keys($this->_attributes) as $key) { - if ($this->_attributes[$key]['name'] == String::upper($name)) { - $this->_attributes[$key]['params'] = $params; - $this->_attributes[$key]['value'] = $value; - $this->_attributes[$key]['values'] = $values; - $found = true; - break; - } - } - } - - if ($append || !$found) { - $this->_attributes[] = array( - 'name' => String::upper($name), - 'params' => $params, - 'value' => $value, - 'values' => $values - ); - } - } - - /** - * Sets parameter(s) for an (already existing) attribute. The - * parameter set is merged into the existing set. - * - * @param string $name The name of the attribute. - * @param array $params Array containing any additional parameters for - * this attribute. - * @return boolean True on success, false if no attribute $name exists. - */ - function setParameter($name, $params = array()) - { - $keys = array_keys($this->_attributes); - foreach ($keys as $key) { - if ($this->_attributes[$key]['name'] == $name) { - $this->_attributes[$key]['params'] = - array_merge($this->_attributes[$key]['params'], $params); - return true; - } - } - - return false; - } - - /** - * Get the value of an attribute. - * - * @param string $name The name of the attribute. - * @param boolean $params Return the parameters for this attribute instead - * of its value. - * - * @return mixed (object) PEAR_Error if the attribute does not exist. - * (string) The value of the attribute. - * (array) The parameters for the attribute or - * multiple values for an attribute. - */ - function getAttribute($name, $params = false) - { - $result = array(); - foreach ($this->_attributes as $attribute) { - if ($attribute['name'] == $name) { - if ($params) { - $result[] = $attribute['params']; - } else { - $result[] = $attribute['value']; - } - } - } - if (!count($result)) { - require_once 'PEAR.php'; - return PEAR::raiseError('Attribute "' . $name . '" Not Found'); - } if (count($result) == 1 && !$params) { - return $result[0]; - } else { - return $result; - } - } - - /** - * Gets the values of an attribute as an array. Multiple values - * are possible due to: - * - * a) multiplce occurences of 'name' - * b) (unsecapd) comma seperated lists. - * - * So for a vcard like "KEY:a,b\nKEY:c" getAttributesValues('KEY') - * will return array('a', 'b', 'c'). - * - * @param string $name The name of the attribute. - * @return mixed (object) PEAR_Error if the attribute does not exist. - * (array) Multiple values for an attribute. - */ - function getAttributeValues($name) - { - $result = array(); - foreach ($this->_attributes as $attribute) { - if ($attribute['name'] == $name) { - $result = array_merge($attribute['values'], $result); - } - } - if (!count($result)) { - return PEAR::raiseError('Attribute "' . $name . '" Not Found'); - } - return $result; - } - - /** - * Returns the value of an attribute, or a specified default value - * if the attribute does not exist. - * - * @param string $name The name of the attribute. - * @param mixed $default What to return if the attribute specified by - * $name does not exist. - * - * @return mixed (string) The value of $name. - * (mixed) $default if $name does not exist. - */ - function getAttributeDefault($name, $default = '') - { - $value = $this->getAttribute($name); - return is_a($value, 'PEAR_Error') ? $default : $value; - } - - /** - * Remove all occurences of an attribute. - * - * @param string $name The name of the attribute. - */ - function removeAttribute($name) - { - $keys = array_keys($this->_attributes); - foreach ($keys as $key) { - if ($this->_attributes[$key]['name'] == $name) { - unset($this->_attributes[$key]); - } - } - } - - /** - * Get attributes for all tags or for a given tag. - * - * @param string $tag Return attributes for this tag, or all attributes if - * not given. - * - * @return array An array containing all the attributes and their types. - */ - function getAllAttributes($tag = false) - { - if ($tag === false) { - return $this->_attributes; - } - $result = array(); - foreach ($this->_attributes as $attribute) { - if ($attribute['name'] == $tag) { - $result[] = $attribute; - } - } - return $result; - } - - /** - * Add a vCalendar component (eg vEvent, vTimezone, etc.). - * - * @param Horde_iCalendar $component Component (subclass) to add. - */ - function addComponent($component) - { - if (is_a($component, 'Horde_iCalendar')) { - $component->_container = &$this; - $this->_components[] = &$component; - } - } - - /** - * Retrieve all the components. - * - * @return array Array of Horde_iCalendar objects. - */ - function getComponents() - { - return $this->_components; - } - - function getType() - { - return 'vcalendar'; - } - - /** - * Return the classes (entry types) we have. - * - * @return array Hash with class names Horde_iCalendar_xxx as keys - * and number of components of this class as value. - */ - function getComponentClasses() - { - $r = array(); - foreach ($this->_components as $c) { - $cn = strtolower(get_class($c)); - if (empty($r[$cn])) { - $r[$cn] = 1; - } else { - $r[$cn]++; - } - } - - return $r; - } - - /** - * Number of components in this container. - * - * @return integer Number of components in this container. - */ - function getComponentCount() - { - return count($this->_components); - } - - /** - * Retrieve a specific component. - * - * @param integer $idx The index of the object to retrieve. - * - * @return mixed (boolean) False if the index does not exist. - * (Horde_iCalendar_*) The requested component. - */ - function getComponent($idx) - { - if (isset($this->_components[$idx])) { - return $this->_components[$idx]; - } else { - return false; - } - } - - /** - * Locates the first child component of the specified class, and returns a - * reference to it. - * - * @param string $type The type of component to find. - * - * @return boolean|Horde_iCalendar_* False if no subcomponent of the - * specified class exists or a reference - * to the requested component. - */ - function &findComponent($childclass) - { - $childclass = 'Horde_iCalendar_' . String::lower($childclass); - $keys = array_keys($this->_components); - foreach ($keys as $key) { - if (is_a($this->_components[$key], $childclass)) { - return $this->_components[$key]; - } - } - - $component = false; - return $component; - } - - /** - * Locates the first matching child component of the specified class, and - * returns a reference to it. - * - * @param string $childclass The type of component to find. - * @param string $attribute This attribute must be set in the component - * for it to match. - * @param string $value Optional value that $attribute must match. - * - * @return boolean|Horde_iCalendar_* False if no matching subcomponent of - * the specified class exists, or a - * reference to the requested component. - */ - function &findComponentByAttribute($childclass, $attribute, $value = null) - { - $childclass = 'Horde_iCalendar_' . String::lower($childclass); - $keys = array_keys($this->_components); - foreach ($keys as $key) { - if (is_a($this->_components[$key], $childclass)) { - $attr = $this->_components[$key]->getAttribute($attribute); - if (is_a($attr, 'PEAR_Error')) { - continue; - } - if ($value !== null && $value != $attr) { - continue; - } - return $this->_components[$key]; - } - } - - $component = false; - return $component; - } - - /** - * Clears the iCalendar object (resets the components and attributes - * arrays). - */ - function clear() - { - $this->_components = array(); - $this->_attributes = array(); - } - - /** - * Checks if entry is vcalendar 1.0, vcard 2.1 or vnote 1.1. - * - * These 'old' formats are defined by www.imc.org. The 'new' (non-old) - * formats icalendar 2.0 and vcard 3.0 are defined in rfc2426 and rfc2445 - * respectively. - * - * @since Horde 3.1.2 - */ - function isOldFormat() - { - $retval = true; - switch ($this->getType()) { - case 'vcard': - $retval = ($this->_version < 3); - break; - case 'vNote': - $retval = ($this->_version < 2); - break; - default: - $retval = ($this->_version < 2); - break; - } - return $retval; - } - - /** - * Export as vCalendar format. - * - * @param string $charset The encoding charset for $text. Defaults to - * utf-8 for new format, standard character set for old format. - */ - function exportvCalendar($charset = null) - { - // Default values. - $requiredAttributes['PRODID'] = '-//The Horde Project//Horde_iCalendar Library' . (defined('HORDE_VERSION') ? ', Horde ' . constant('HORDE_VERSION') : '') . '//EN'; - // METHOD is only required for iTip, but not for CalDAV, therefore removing it here calendar_ical sets it anyway by default - //$requiredAttributes['METHOD'] = 'PUBLISH'; - - foreach ($requiredAttributes as $name => $default_value) { - if (is_a($this->getattribute($name), 'PEAR_Error')) { - $this->setAttribute($name, $default_value); - } - } - - return $this->_exportvData('VCALENDAR', $charset); - } - - /** - * Export this entry as a hash array with tag names as keys. - * - * @param boolean $paramsInKeys - * If false, the operation can be quite lossy as the - * parameters are ignored when building the array keys. - * So if you export a vcard with - * LABEL;TYPE=WORK:foo - * LABEL;TYPE=HOME:bar - * the resulting hash contains only one label field! - * If set to true, array keys look like 'LABEL;TYPE=WORK' - * @return array A hash array with tag names as keys. - */ - function toHash($paramsInKeys = false) - { - $hash = array(); - foreach ($this->_attributes as $a) { - $k = $a['name']; - if ($paramsInKeys && is_array($a['params'])) { - foreach ($a['params'] as $p => $v) { - $k .= ";$p=$v"; - } - } - $hash[$k] = $a['value']; - } - - return $hash; - } - - /** - * Parses a string containing vCalendar data. - * - * @todo This method doesn't work well at all, if $base is VCARD. - * - * @param string $text The data to parse. - * @param string $base The type of the base object. - * @param string $charset The encoding charset for $text. Defaults to - * utf-8 for new format, iso-8859-1 for old format. - * @param boolean $clear If true clears the iCal object before parsing. - * - * @return boolean True on successful import, false otherwise. - */ - function parsevCalendar($text, $base = 'VCALENDAR', $charset = null, $clear = true) - { - if ($clear) { - $this->clear(); - } - - if ($base == 'VTODO' && - preg_match('/^BEGIN:VTODO(.*)^END:VEVENT/ism', $text, $matches)) { - // Workaround for Funambol VTODO bug in Mozilla Sync Plugins - Horde::logMessage('iCalendar: Funambol VTODO-bug detected, workaround activated...', - __FILE__, __LINE__, PEAR_LOG_WARNING); - $container = true; - $vCal = $matches[1]; - } elseif (preg_match('/^BEGIN:' . $base . '(.*)^END:' . $base . '/ism', $text, $matches)) { - $container = true; - $vCal = $matches[1]; - } else { - // Text isn't enclosed in BEGIN:VCALENDAR - // .. END:VCALENDAR. We'll try to parse it anyway. - $container = false; - $vCal = $text; - } - - if (preg_match('/^VERSION:(\d\.\d)\s*$/ism', $vCal, $matches)) { - // define the version asap - #Horde::logMessage("iCalendar VERSION:" . $matches[1], __FILE__, __LINE__, PEAR_LOG_DEBUG); - $this->setAttribute('VERSION', $matches[1]); - } - - // Preserve a trailing CR - $vCal = trim($vCal) . "\n"; - - // All subcomponents. - $matches = null; - // Workaround for Funambol VTODO bug in Mozilla Sync Plugins - if (preg_match_all('/^BEGIN:(VTODO)(\r\n|\r|\n)(.*)^END:VEVENT/Uims', $vCal, $matches) || - preg_match_all('/^BEGIN:(.*)(\r\n|\r|\n)(.*)^END:\1/Uims', $vCal, $matches)) { - // vTimezone components are processed first. They are - // needed to process vEvents that may use a TZID. - foreach ($matches[0] as $key => $data) { - $type = trim($matches[1][$key]); - if ($type != 'VTIMEZONE') { - continue; - } - $component = &Horde_iCalendar::newComponent($type, $this); - if ($component === false) { - return PEAR::raiseError("Unable to create object for type $type"); - } - $component->parsevCalendar($data, $type, $charset); - - $this->addComponent($component); - - // Remove from the vCalendar data. - $vCal = str_replace($data, '', $vCal); - } - - // Now process the non-vTimezone components. - foreach ($matches[0] as $key => $data) { - $type = trim($matches[1][$key]); - if ($type == 'VTIMEZONE') { - continue; - } - $component = &Horde_iCalendar::newComponent($type, $this); - if ($component === false) { - return PEAR::raiseError("Unable to create object for type $type"); - } - $component->parsevCalendar($data, $type, $charset); - - $this->addComponent($component); - - // Remove from the vCalendar data. - $vCal = str_replace($data, '', $vCal); - } - } elseif (!$container) { - return false; - } - - // Unfold "quoted printable" folded lines like: - // BODY;ENCODING=QUOTED-PRINTABLE:= - // another=20line= - // last=20line - while (preg_match_all('/^([^:]+;\s*((ENCODING=)?QUOTED-PRINTABLE|ENCODING=[Q|q])(.*=\r?\n)+(.*[^=])?\r?\n)/mU', $vCal, $matches)) { - foreach ($matches[1] as $s) { - if ($this->isOldFormat()) { - $r = preg_replace('/=\r?\n([ \t])?/', '\1', $s); - } else { - $r = preg_replace('/=\r?\n[ \t]*/', '', $s); - } - $vCal = str_replace($s, $r, $vCal); - } - } - - // Unfold any folded lines. - if ($this->isOldFormat()) { - // old formats force folding at whitespace which must therefore be preserved - $vCal = preg_replace('/[\r\n]+([ \t])/', '\1', $vCal); - } else { - $vCal = preg_replace('/[\r\n]+[ \t]/', '', $vCal); - } - - $isDate = false; - - // Parse the remaining attributes. - if (preg_match_all('/^((?:[^":]+|(?:"[^"]*")+)*):([^\r\n]*)\r?$/m', $vCal, $matches)) { - foreach ($matches[0] as $attribute) { - preg_match('/([^:;]*)((;(?:(?:[^":\\\]*(?:\\\.)?)+|(?:"[^"]*")+)*)?):([^\r\n]*)[\r\n]*/', $attribute, $parts); - $tag = trim(String::upper($parts[1])); - $value = $parts[4]; - $params = array(); - - // Parse parameters. - if (!empty($parts[2])) { - preg_match_all('/;(([^;=]*)(=("[^"]*"|(?:[^;\\\]*(?:\\\.)?)*))?)/', $parts[2], $param_parts); - foreach ($param_parts[2] as $key => $paramName) { - $paramName = String::upper($paramName); - $paramValue = $param_parts[4][$key]; - if ($paramName == 'TYPE') { - $paramValue = preg_split('/(?translation->convert($value, $params['CHARSET']); - } else { - $value = $GLOBALS['egw']->translation->convert($value, - empty($charset) ? ($this->isOldFormat() ? 'iso-8859-1' : 'utf-8') : $charset); - } - // Funambol hack :-( - $value = str_replace('\\\\n', "\n", $value); - break; - case 'B': - case 'BASE64': - $value = base64_decode($value); - break; - } - } elseif (isset($params['CHARSET'])) { - $value = $GLOBALS['egw']->translation->convert($value, $params['CHARSET']); - } else { - // As per RFC 2279, assume UTF8 if we don't have an - // explicit charset parameter. - $value = $GLOBALS['egw']->translation->convert($value, - empty($charset) ? ($this->isOldFormat() ? 'iso-8859-1' : 'utf-8') : $charset); - } - - // Get timezone info for date fields from $params. - $tzid = isset($params['TZID']) ? trim($params['TZID'], '\"') : false; - - switch ($tag) { - case 'VERSION': // already processed - break; - // Date fields. - case 'COMPLETED': - case 'CREATED': - case 'LAST-MODIFIED': - $this->setAttribute($tag, $this->_parseDateTime($value, $tzid), $params); - break; - - case 'BDAY': - case 'X-SYNCJE-ANNIVERSARY': - $this->setAttribute($tag, $value, $params, true, $this->_parseDate($value)); - break; - - case 'DTEND': - case 'DTSTART': - case 'DTSTAMP': - case 'DUE': - case 'AALARM': - case 'DALARM': - case 'RECURRENCE-ID': - case 'X-RECURRENCE-ID': - // types like AALARM may contain additional data after a ; - // ignore these. - $ts = explode(';', $value); - if (isset($params['VALUE']) && $params['VALUE'] == 'DATE') { - $isDate = true; - $this->setAttribute($tag, $this->_parseDateTime($ts[0], $tzid), $params, true, $this->_parseDate($ts[0])); - } else { - $this->setAttribute($tag, $this->_parseDateTime($ts[0], $tzid), $params); - } - break; - - case 'TRIGGER': - if (isset($params['VALUE'])) { - if ($params['VALUE'] == 'DATE-TIME') { - $this->setAttribute($tag, $this->_parseDateTime($value, $tzid), $params); - } else { - $this->setAttribute($tag, $this->_parseDuration($value), $params); - } - } else { - $this->setAttribute($tag, $this->_parseDuration($value), $params); - } - break; - - // Comma or semicolon seperated dates. - case 'EXDATE': - case 'RDATE': - $dates = array(); - preg_match_all('/[;,]([^;,]*)/', ';' . $value, $values); - - foreach ($values[1] as $value) { - if ((isset($params['VALUE']) - && $params['VALUE'] == 'DATE') || (!isset($params['VALUE']) && $isDate)) { - $dates[] = $this->_parseDate(trim($value)); - } else { - $dates[] = $this->_parseDateTime(trim($value), $tzid); - } - } - $this->setAttribute($tag, isset($dates[0]) ? $dates[0] : null, $params, true, $dates); - break; - - // Duration fields. - case 'DURATION': - $this->setAttribute($tag, $this->_parseDuration($value), $params); - break; - - // Period of time fields. - case 'FREEBUSY': - $periods = array(); - preg_match_all('/,([^,]*)/', ',' . $value, $values); - foreach ($values[1] as $value) { - $periods[] = $this->_parsePeriod($value); - } - - $this->setAttribute($tag, isset($periods[0]) ? $periods[0] : null, $params, true, $periods); - break; - - // UTC offset fields. - case 'TZOFFSETFROM': - case 'TZOFFSETTO': - $this->setAttribute($tag, $this->_parseUtcOffset($value), $params); - break; - - // Integer fields. - case 'PERCENT-COMPLETE': - case 'PRIORITY': - case 'REPEAT': - case 'SEQUENCE': - $this->setAttribute($tag, intval($value), $params); - break; - - // Geo fields. - case 'GEO': - if ($this->isOldFormat()) { - $floats = explode(',', $value); - $value = array('latitude' => floatval($floats[1]), - 'longitude' => floatval($floats[0])); - } else { - $floats = explode(';', $value); - $value = array('latitude' => floatval($floats[0]), - 'longitude' => floatval($floats[1])); - } - $this->setAttribute($tag, $value, $params); - break; - - // Recursion fields. # add more flexibility - #case 'EXRULE': - #case 'RRULE': - # $this->setAttribute($tag, trim($value), $params); - # break; - - // Binary fields. - case 'PHOTO': - $this->setAttribute($tag, $value, $params); - break; - - // ADR, ORG and N are lists seperated by unescaped semicolons - // with a specific number of slots. - case 'ADR': - case 'N': - case 'ORG': - $value = trim($value); - // As of rfc 2426 2.4.2 semicolon, comma, and colon must - // be escaped (semicolon is unescaped after splitting below). - $value = str_replace(array('\\n', '\\N', '\\,', '\\:'), - array("\n", "\n", ',', ':'), - $value); - - // Split by unescaped semicolons: - $values = preg_split('/(?setAttribute($tag, trim($value), $params, true, $values); - break; - - // CATEGORIES is a lists seperated by unescaped commas - // with a unspecific number of slots. - case 'CATEGORIES': - $value = trim($value); - // As of rfc 2426 2.4.2 semicolon, comma, and colon must - // be escaped (comma is unescaped after splitting below). - $value = str_replace(array('\\n', '\\N', '\\;', '\\:'), - array("\n", "\n", ';', ':'), - $value); - - // Split by unescaped commas: - $values = preg_split('/(?setAttribute($tag, trim($value), $params, true, $values); - break; - - // String fields. - default: - if ($this->isOldFormat()) { - $value = trim($value); - // vCalendar 1.0 and vCard 2.1 only escape semicolons - // and use unescaped semicolons to create lists. - $value = str_replace(array('\\n', '\\N', '\\,', '\\:'), - array("\n", "\n", ',', ':'), - $value); - - // Split by unescaped semicolons: - $values = preg_split('/(?setAttribute($tag, trim($value), $params, true, $values); - } else { - $value = trim($value); - // As of rfc 2426 2.4.2 semicolon, comma, and colon - // must be escaped (comma is unescaped after splitting - // below). - $value = str_replace(array('\\n', '\\N', '\\;', '\\:', '\\\\'), - array("\n", "\n", ';', ':', '\\'), - $value); - - // Split by unescaped commas. - $values = preg_split('/(?setAttribute($tag, trim($value), $params, true, $values); - } - break; - } - } - } - - return true; - } - - /** - * Export this component in vCal format. - * - * @param string $base The type of the base object. - * @param string $charset The encoding charset for $text. Defaults to - * utf-8 for new format, standard character set for old format. - * - * @return string vCal format data. - */ - function _exportvData($base = 'VCALENDAR', $charset = null) - { - $base = String::upper($base); - - $result = 'BEGIN:' . $base . $this->_newline; - - // VERSION is not allowed for entries enclosed in VCALENDAR/ICALENDAR, - // as it is part of the enclosing VCALENDAR/ICALENDAR. See rfc2445 - if ($base !== 'VEVENT' && $base !== 'VTODO' && $base !== 'VALARM' && - $base !== 'VJOURNAL' && $base !== 'VFREEBUSY' && - $base !== 'VTIMEZONE' && $base !== 'STANDARD' && $base != 'DAYLIGHT') { - // Ensure that version is the first attribute. - $result .= 'VERSION:' . $this->_version . $this->_newline; - } - - if (empty($charset)) { - if ($this->isOldFormat()) { - $charset = NLS::getCharset(); - } else { - $charset = 'utf-8'; - } - } - - foreach ($this->_attributes as $attribute) { - $name = $attribute['name']; - if ($name == 'VERSION') { - // Already done. - continue; - } - - $params_str = ''; - $params = $attribute['params']; - if ($params) { - foreach ($params as $param_name => $param_value) { - /* Skip CHARSET for iCalendar 2.0 data, not allowed. */ - if ($param_name == 'CHARSET') { - if (!$this->isOldFormat() || empty($param_value)) { - continue; - } else { - $param_value = String::Upper($param_value); - } - } - if ($param_name == 'ENCODING') { - continue; - } - /* Skip VALUE=DATE for vCalendar 1.0 data, not allowed. */ - if ($this->isOldFormat() && - $param_name == 'VALUE' && $param_value == 'DATE') { - continue; - } - /* Skip TZID for iCalendar 1.0 data, not supported. */ - if ($this->isOldFormat() && $param_name == 'TZID') { - continue; - } - // Skip CN in ATTENDEE adn ORGANIZER for vCalendar 1.0 - if ($this->isOldFormat() && $param_name == 'CN' && - ($name == 'ATTENDEE' || $name == 'ORGANIZER')) { - continue; - } - if ($param_value === null) { - $params_str .= ";$param_name"; - } else { - $params_str .= ";$param_name=$param_value"; - } - } - } - - $value = $attribute['value']; - - switch ($name) { - // Date fields. - case 'COMPLETED': - case 'CREATED': - case 'DCREATED': - case 'LAST-MODIFIED': - $value = $this->_exportDateTime($value); - break; - - // Support additional fields after date. - case 'AALARM': - case 'DALARM': - if (isset($params['VALUE'])) { - if ($params['VALUE'] == 'DATE') { - // VCALENDAR 1.0 uses T000000 - T235959 for all day events: - if ($this->isOldFormat() && $name == 'DTEND') { - $d = new Horde_Date($value); - $value = new Horde_Date(array( - 'year' => $d->year, - 'month' => $d->month, - 'mday' => $d->mday - 1)); - $value->correct(); - $value = $this->_exportDate($value, '235959'); - } else { - $value = $this->_exportDate($value, '000000'); - } - } else { - $value = $this->_exportDateTime($value); - } - } else { - $value = $this->_exportDateTime($value); - } - - if (is_array($attribute['values']) && - count($attribute['values']) > 0) { - $values = $attribute['values']; - if ($this->isOldFormat()) { - $values = str_replace(';', '\\;', $values); - } else { - // As of rfc 2426 2.5 semicolon and comma must be - // escaped. - $values = str_replace(array('\\', ';', ','), - array('\\\\', '\\;', '\\,'), - $values); - } - $value .= ';' . implode(';', $values); - } - - break; - - case 'DTEND': - case 'DTSTART': - case 'DTSTAMP': - case 'DUE': - case 'RECURRENCE-ID': - case 'X-RECURRENCE-ID': - if (isset($params['VALUE'])) { - if ($params['VALUE'] == 'DATE') { - // VCALENDAR 1.0 uses T000000 - T235959 for all day events: - if ($this->isOldFormat() && $name == 'DTEND') { - $d = new Horde_Date($value); - $value = new Horde_Date(array( - 'year' => $d->year, - 'month' => $d->month, - 'mday' => $d->mday - 1)); - $value->correct(); - $value = $this->_exportDate($value, '235959'); - } else { - $value = $this->_exportDate($value, '000000'); - } - } else { - $value = $this->_exportDateTime($value); - } - } else { - $value = $this->_exportDateTime($value); - } - break; - - // Comma or semicolon seperated dates. - case 'EXDATE': - case 'RDATE': - if (is_array($attribute['values'])) { - $values = $attribute['values']; - } elseif (!empty($value)) { - if ($this->isOldFormat()) { - $values = explode(';', $value); - } else { - $values = explode(',', $value); - } - } else { - break; - } - $dates = array(); - foreach ($values as $date) { - if (isset($params['VALUE'])) { - if ($params['VALUE'] == 'DATE') { - $dates[] = $this->_exportDate($date, '000000'); - } elseif ($params['VALUE'] == 'PERIOD') { - $dates[] = $this->_exportPeriod($date); - } else { - $dates[] = $this->_exportDateTime($date); - } - } else { - $dates[] = $this->_exportDateTime($date); - } - } - if ($this->isOldFormat()) { - $value = implode(';', $dates); - } else { - $value = implode(',', $dates); - } - break; - - case 'TRIGGER': - if (isset($params['VALUE'])) { - if ($params['VALUE'] == 'DATE-TIME') { - $value = $this->_exportDateTime($value); - } elseif ($params['VALUE'] == 'DURATION') { - $value = $this->_exportDuration($value); - } - } else { - $value = $this->_exportDuration($value); - } - break; - - // Duration fields. - case 'DURATION': - $value = $this->_exportDuration($value); - break; - - // Period of time fields. - case 'FREEBUSY': - $value_str = ''; - foreach ($value as $period) { - $value_str .= empty($value_str) ? '' : ','; - $value_str .= $this->_exportPeriod($period); - } - $value = $value_str; - break; - - // UTC offset fields. - case 'TZOFFSETFROM': - case 'TZOFFSETTO': - $value = $this->_exportUtcOffset($value); - break; - - // Integer fields. - case 'PERCENT-COMPLETE': - case 'PRIORITY': - case 'REPEAT': - case 'SEQUENCE': - $value = "$value"; - break; - - // Geo fields. - case 'GEO': - if ($this->isOldFormat()) { - $value = $value['longitude'] . ',' . $value['latitude']; - } else { - $value = $value['latitude'] . ';' . $value['longitude']; - } - break; - - // Recurrence fields. - case 'EXRULE': - break; - - case 'RRULE': - if (!empty($params_str) && $params_str[0] == ';') - { - // The standard requires a double colon RRULE:... - $params_str[0] = ':'; - } - break; - - case 'PHOTO': - break; - - default: - if ($this->isOldFormat()) { - if (is_array($attribute['values']) && - count($attribute['values']) > 1) { - $values = $attribute['values']; - if ($name == 'N' || $name == 'ADR' || $name == 'ORG') { - $glue = ';'; - } else { - $glue = ','; - } - $values = str_replace(';', '\\;', $values); - $value = implode($glue, $values); - } else { - /* vcard 2.1 and vcalendar 1.0 escape only - * semicolons */ - $value = str_replace(';', '\\;', $value); - } - // Text containing newlines or ASCII >= 127 must be BASE64 - // or QUOTED-PRINTABLE encoded. Currently we use - // QUOTED-PRINTABLE as default. - if (preg_match('/[^\x20-\x7F]/', $value) && - !isset($params['ENCODING'])) { - $params['ENCODING'] = 'QUOTED-PRINTABLE'; - } - if (preg_match('/([\177-\377])/', $value) && - !isset($params['CHARSET'])) { - // Add CHARSET as well. At least the synthesis client - // gets confused otherwise - $params['CHARSET'] = String::upper($charset); - $params_str .= ';CHARSET=' . $params['CHARSET']; - } - } else { - if (is_array($attribute['values']) && - count($attribute['values']) > 1) { - $values = $attribute['values']; - if ($name == 'N' || $name == 'ADR' || $name == 'ORG') { - $glue = ';'; - } else { - $glue = ','; - } - // As of rfc 2426 2.5 semicolon and comma must be - // escaped. - $values = str_replace(array('\\', ';', ','), - array('\\\\', '\\;', '\\,'), - $values); - $value = implode($glue, $values); - } else { - // As of rfc 2426 2.5 semicolon and comma must be - // escaped. - $value = str_replace(array('\\', ';', ','), - array('\\\\', '\\;', '\\,'), - $value); - } - $value = preg_replace('/\r?\n/', "\n", $value); - } - } - - $encoding = (!empty($params['ENCODING']) && strlen(trim($value)) > 0); - - if ($encoding) { - switch($params['ENCODING']) { - case 'Q': - case 'QUOTED-PRINTABLE': - if (!$this->isOldFormat()) - { - $encoding = false; - break; - } - $params_str .= ';ENCODING=' . $params['ENCODING']; - $value = str_replace("\r", '', $value); - $result .= $name . $params_str . ':' - . str_replace('=0A', '=0D=0A', - $this->_quotedPrintableEncode($value)) - . $this->_newline; - break; - case 'FUNAMBOL-QP': - // Funambol needs some special quoting - $value = str_replace(array('<', "\r"), array('<', ''), $value); - if (!$this->isOldFormat()) - { - $encoding = false; - break; - } - $params_str .= ';ENCODING=QUOTED-PRINTABLE'; - $result .= $name . $params_str . ':' - . str_replace('=0A', '=0D=0A', - $this->_quotedPrintableEncode($value, false)) - . $this->_newline; - break; - case 'B': - case 'BASE64': - $params_str .= ';ENCODING=' . $params['ENCODING']; - // using native php wordwrap to speed up encoding of images - $result .= wordwrap($name . $params_str . ':' . $this->_newline . ' ' . - $this->_base64Encode($value),75,$this->_newline . ' ',true) . $this->_newline; - /* - $attr_string = $name . $params_str . ':' . $this->_newline . ' ' . $this->_base64Encode($value); - $attr_string = String::wordwrap($attr_string, 75, $this->_newline . ' ', - true, 'utf-8', true); // charset does not matter - $result .= $attr_string . $this->_newline; - */ - if ($this->isOldFormat()) { - $result .= $this->_newline; // Append an empty line - } - } - } - - if (!$encoding) { - $value = str_replace(array("\r", "\n"), array('', '\\n'), $value); - $attr_string = $name . $params_str; - if (strlen($value) > 0) { - $attr_string .= ':' . $value; - } elseif ($name != 'RRULE') { - $attr_string .= ':'; - } - if (!$this->isOldFormat()) { - $attr_string = String::wordwrap($attr_string, 75, $this->_newline . ' ', - true, $charset, true); - } - $result .= $attr_string . $this->_newline; - } - } - - foreach ($this->_components as $component) { - if ($this->isOldFormat() && $component->getType() == 'vTimeZone') { - // Not supported - continue; - } - $result .= $component->exportvCalendar($charset); - } - - return $result . 'END:' . $base . $this->_newline; - } - - /** - * Parse a UTC Offset field. - */ - function _parseUtcOffset($text) - { - $offset = array(); - if (preg_match('/(\+|-)([0-9]{2})([0-9]{2})([0-9]{2})?/', $text, $timeParts)) { - $offset['ahead'] = (bool)($timeParts[1] == '+'); - $offset['hour'] = intval($timeParts[2]); - $offset['minute'] = intval($timeParts[3]); - if (isset($timeParts[4])) { - $offset['second'] = intval($timeParts[4]); - } - return $offset; - } else { - return false; - } - } - - /** - * Export a UTC Offset field. - */ - function _exportUtcOffset($value) - { - $offset = $value['ahead'] ? '+' : '-'; - $offset .= sprintf('%02d%02d', - $value['hour'], $value['minute']); - if (isset($value['second'])) { - $offset .= sprintf('%02d', $value['second']); - } - - return $offset; - } - - /** - * Parse a Time Period field. - */ - function _parsePeriod($text) - { - $periodParts = explode('/', $text); - - $start = $this->_parseDateTime($periodParts[0]); - - if ($duration = $this->_parseDuration($periodParts[1])) { - return array('start' => $start, 'duration' => $duration); - } elseif ($end = $this->_parseDateTime($periodParts[1])) { - return array('start' => $start, 'end' => $end); - } - } - - /** - * Export a Time Period field. - */ - function _exportPeriod($value) - { - $period = $this->_exportDateTime($value['start']); - $period .= '/'; - if (isset($value['duration'])) { - $period .= $this->_exportDuration($value['duration']); - } else { - $period .= $this->_exportDateTime($value['end']); - } - return $period; - } - - /** - * Grok the TZID and return an offset in seconds from UTC for this - * date and time. - */ - function _parseTZID($date, $time, $tzid) - { - $vtimezone = $this->_container->findComponentByAttribute('vtimezone', 'TZID', $tzid); - if (!$vtimezone) { - return false; - } - - $change_times = array(); - foreach ($vtimezone->getComponents() as $o) { - $t = $vtimezone->parseChild($o, $date['year']); - if ($t !== false) { - $change_times[] = $t; - } - } - - if (!$change_times) { - return false; - } - - sort($change_times); - - // Time is arbitrarily based on UTC for comparison. - $t = @gmmktime($time['hour'], $time['minute'], $time['second'], - $date['month'], $date['mday'], $date['year']); - - if ($t < $change_times[0]['time']) { - return $change_times[0]['from']; - } - - for ($i = 0, $n = count($change_times); $i < $n - 1; $i++) { - if (($t >= $change_times[$i]['time']) && - ($t < $change_times[$i + 1]['time'])) { - return $change_times[$i]['to']; - } - } - - if ($t >= $change_times[$n - 1]['time']) { - return $change_times[$n - 1]['to']; - } - - return false; - } - - /** - * Parses a DateTime field and returns a unix timestamp. If the - * field cannot be parsed then the original text is returned - * unmodified. - * - * @todo This function should be moved to Horde_Date and made public. - */ - function _parseDateTime($text, $tzid = false) - { - $dateParts = explode('T', $text); - if (count($dateParts) != 2 && !empty($text)) { - // Not a datetime field but may be just a date field. - if (!preg_match('/^(\d{4})-?(\d{2})-?(\d{2})$/', $text, $match)) { - // Or not - return $text; - } - $newtext = $text.'T000000'; - $dateParts = explode('T', $newtext); - } - - if (!$date = Horde_iCalendar::_parseDate($dateParts[0])) { - return $text; - } - if (!$time = Horde_iCalendar::_parseTime($dateParts[1])) { - return $text; - } - - // Get timezone info for date fields from $tzid and container. - $tzoffset = ($time['zone'] == 'Local' && $tzid && is_a($this->_container, 'Horde_iCalendar')) - ? $this->_parseTZID($date, $time, $tzid) : false; - if ($time['zone'] == 'UTC' || $tzoffset !== false) { - $result = @gmmktime($time['hour'], $time['minute'], $time['second'], - $date['month'], $date['mday'], $date['year']); - if ($tzoffset) { - $result -= $tzoffset; - } - } else { - // We don't know the timezone so assume local timezone. - // FIXME: shouldn't this be based on the user's timezone - // preference rather than the server's timezone? - $result = @mktime($time['hour'], $time['minute'], $time['second'], - $date['month'], $date['mday'], $date['year']); - } - - return ($result !== false) ? $result : $text; - } - - /** - * Export a DateTime field. - */ - function _exportDateTime($value) - { - if (is_numeric($value)) { - $temp = array(); - $tz = date('O', $value); - $TZOffset = (3600 * substr($tz, 0, 3)) + (60 * substr(date('O', $value), 3, 2)); - $value -= $TZOffset; - - $temp['zone'] = 'UTC'; - $temp['year'] = date('Y', $value); - $temp['month'] = date('n', $value); - $temp['mday'] = date('j', $value); - $temp['hour'] = date('G', $value); - $temp['minute'] = date('i', $value); - $temp['second'] = date('s', $value); - return Horde_iCalendar::_exportDate($temp) . 'T' . Horde_iCalendar::_exportTime($temp); - } else if (is_object($value) || is_array($value)) { - $dateOb = new Horde_Date($value); - return Horde_iCalendar::_exportDateTime($dateOb->timestamp()); - } - return $value; // nothing to do with us, let's not touch it - } - - /** - * Parses a Time field. - * - * @static - */ - function _parseTime($text) - { - if (preg_match('/([0-9]{2})([0-9]{2})([0-9]{2})(Z)?/', $text, $timeParts)) { - $time['hour'] = intval($timeParts[1]); - $time['minute'] = intval($timeParts[2]); - $time['second'] = intval($timeParts[3]); - if (isset($timeParts[4])) { - $time['zone'] = 'UTC'; - } else { - $time['zone'] = 'Local'; - } - return $time; - } else { - return false; - } - } - - /** - * Exports a Time field. - */ - function _exportTime($value) - { - $time = sprintf('%02d%02d%02d', - $value['hour'], $value['minute'], $value['second']); - if ($value['zone'] == 'UTC') { - $time .= 'Z'; - } - return $time; - } - - /** - * Parses a Date field. - * - * @static - */ - function _parseDate($text) - { - $parts = explode('T', $text); - if (count($parts) == 2) { - $text = $parts[0]; - } - - if (!preg_match('/^(\d{4})-?(\d{2})-?(\d{2})$/', $text, $match)) { - return false; - } - - return array('year' => $match[1], - 'month' => $match[2], - 'mday' => $match[3]); - } - - /** - * Exports a date field. - * - * @param object|array $value Date object or hash. - * @param string $autoconvert If set, use this as time part to export the - * date as datetime when exporting to Vcalendar - * 1.0. Examples: '000000' or '235959' - */ - function _exportDate($value, $autoconvert = false) - { - if (is_object($value)) { - $value = array('year' => $value->year, 'month' => $value->month, 'mday' => $value->mday); - } - if ($autoconvert !== false && $this->isOldFormat()) { - return sprintf('%04d%02d%02dT%s', $value['year'], $value['month'], $value['mday'], $autoconvert); - } else { - return sprintf('%04d%02d%02d', $value['year'], $value['month'], $value['mday']); - } - } - - /** - * Parse a Duration Value field. - */ - function _parseDuration($text) - { - if (preg_match('/([+]?|[-])P(([0-9]+W)|([0-9]+D)|)(T(([0-9]+H)|([0-9]+M)|([0-9]+S))+)?/', trim($text), $durvalue)) { - // Weeks. - $duration = 7 * 86400 * intval($durvalue[3]); - - if (count($durvalue) > 4) { - // Days. - $duration += 86400 * intval($durvalue[4]); - } - if (count($durvalue) > 5) { - // Hours. - $duration += 3600 * intval($durvalue[7]); - - // Mins. - if (isset($durvalue[8])) { - $duration += 60 * intval($durvalue[8]); - } - - // Secs. - if (isset($durvalue[9])) { - $duration += intval($durvalue[9]); - } - } - - // Sign. - if ($durvalue[1] == "-") { - $duration *= -1; - } - - return $duration; - } else { - return false; - } - } - - /** - * Export a duration value. - */ - function _exportDuration($value) - { - $duration = ''; - if ($value < 0) { - $value *= -1; - $duration .= '-'; - } - $duration .= 'P'; - - $weeks = floor($value / (7 * 86400)); - $value = $value % (7 * 86400); - if ($weeks) { - $duration .= $weeks . 'W'; - } - - $days = floor($value / (86400)); - $value = $value % (86400); - if ($days) { - $duration .= $days . 'D'; - } - - if ($value) { - $duration .= 'T'; - - $hours = floor($value / 3600); - $value = $value % 3600; - if ($hours) { - $duration .= $hours . 'H'; - } - - $mins = floor($value / 60); - $value = $value % 60; - if ($mins) { - $duration .= $mins . 'M'; - } - - if ($value) { - $duration .= $value . 'S'; - } - } - // duration without time ("P") is NOT valid, append 0 minutes ("T0M") - elseif ($duration === 'P') - { - $duration .= 'T0M'; - } - - return $duration; - } - - - /** - * Convert an 8bit string to a base64 string - * to RFC2045, section 6.7. - * - * @param string $input The string to be encoded. - * - * @return string The base64 encoded string. - */ - function _base64Encode($input = '') - { - return base64_encode($input); - } - - - /** - * Converts an 8bit string to a quoted-printable string according to RFC - * 2045, section 6.7. - * - * imap_8bit() does not apply all necessary rules. - * - * @param string $input The string to be encoded. - * - * @return string The quoted-printable encoded string. - */ - function _quotedPrintableEncode($input = '', $withFolding=true) - { - $output = $line = ''; - $len = bytes($input); - - for ($i = 0; $i < $len; ++$i) { - $ord = ord($input[$i]); - // Encode non-printable characters (rule 2). - if ($ord == 9 || - ($ord >= 32 && $ord <= 60) || - ($ord >= 62 && $ord <= 126)) { - $chunk = $input[$i]; - } else { - // Quoted printable encoding (rule 1). - $chunk = '=' . String::upper(sprintf('%02X', $ord)); - } - $line .= $chunk; - // Wrap long lines (rule 5) - if ($withFolding && strlen($line) + 1 > 76) { - $line = String::wordwrap($line, 75, "=\r\n", true, 'us-ascii', true); - $newline = strrchr($line, "\r\n"); - if ($newline !== false) { - $output .= substr($line, 0, -strlen($newline) + 2); - $line = substr($newline, 2); - } else { - $output .= $line; - } - continue; - } - // Wrap at line breaks for better readability (rule 4). - if ($withFolding && substr($line, -3) == '=0A') { - $output .= $line . "=\r\n"; - $line = ''; - } - } - $output .= $line; - - // Trailing whitespace must be encoded (rule 3). - $lastpos = strlen($output) - 1; - if ($output[$lastpos] == chr(9) || - $output[$lastpos] == chr(32)) { - $output[$lastpos] = '='; - $output .= String::upper(sprintf('%02X', ord($output[$lastpos]))); - } - - return $output; - } - -} diff --git a/phpgwapi/inc/horde/Horde/iCalendar/valarm.php b/phpgwapi/inc/horde/Horde/iCalendar/valarm.php deleted file mode 100644 index 224c44bc5e..0000000000 --- a/phpgwapi/inc/horde/Horde/iCalendar/valarm.php +++ /dev/null @@ -1,28 +0,0 @@ - - * @since Horde 3.0 - * @package Horde_iCalendar - */ -class Horde_iCalendar_valarm extends Horde_iCalendar { - - function getType() - { - return 'vAlarm'; - } - - function exportvCalendar() - { - return parent::_exportvData('VALARM'); - } - -} diff --git a/phpgwapi/inc/horde/Horde/iCalendar/vcard.php b/phpgwapi/inc/horde/Horde/iCalendar/vcard.php deleted file mode 100644 index a814246758..0000000000 --- a/phpgwapi/inc/horde/Horde/iCalendar/vcard.php +++ /dev/null @@ -1,138 +0,0 @@ - - * @package Horde_iCalendar - */ -class Horde_iCalendar_vcard extends Horde_iCalendar { - - function Horde_iCalendar_vcard($version = '2.1') - { - return parent::Horde_iCalendar($version); - } - - function getType() - { - return 'vcard'; - } - - /** - * Unlike vevent and vtodo, a vcard is normally not enclosed in an - * iCalendar container. (BEGIN..END) - */ - function exportvCalendar() - { - $requiredAttributes['VERSION'] = $this->_version; - $requiredAttributes['N'] = ';;;;;;'; - if ($this->_version == '3.0') { - $requiredAttributes['FN'] = ''; - } - - foreach ($requiredAttributes as $name => $default_value) { - if (is_a($this->getAttribute($name), 'PEAR_Error')) { - $this->setAttribute($name, $default_value); - } - } - - return $this->_exportvData('VCARD'); - } - - /** - * Returns the contents of the "N" tag as a printable Name: - * i.e. converts: - * - * N:Duck;Dagobert;T;Professor;Sen. - * to - * "Professor Dagobert T Duck Sen" - * - * @return string Full name of vcard "N" tag or null if no N tag. - */ - function printableName() - { - $name_parts = $this->getAttributeValues('N'); - if (is_a($name_parts, 'PEAR_Error')) { - return null; - } - - $name_arr = array(); - - if (!empty($name_parts[VCARD_N_PREFIX])) { - $name_arr[] = $name_parts[VCARD_N_PREFIX]; - } - if (!empty($name_parts[VCARD_N_GIVEN])) { - $name_arr[] = $name_parts[VCARD_N_GIVEN]; - } - if (!empty($name_parts[VCARD_N_ADDL])) { - $name_arr[] = $name_parts[VCARD_N_ADDL]; - } - if (!empty($name_parts[VCARD_N_FAMILY])) { - $name_arr[] = $name_parts[VCARD_N_FAMILY]; - } - if (!empty($name_parts[VCARD_N_SUFFIX])) { - $name_arr[] = $name_parts[VCARD_N_SUFFIX]; - } - - return implode(' ', $name_arr); - } - - /** - * Static function to make a given email address rfc822 compliant. - * - * @param string $address An email address. - * - * @return string The RFC822-formatted email address. - */ - function getBareEmail($address) - { - // Empty values are still empty. - if (!$address) { - return $address; - } - - require_once 'Mail/RFC822.php'; - require_once 'Horde/MIME.php'; - - static $rfc822; - if (is_null($rfc822)) { - $rfc822 = new Mail_RFC822(); - } - - if (!$rfc822->validateMailbox($address)) { - return $address; - } - return MIME::rfc822WriteAddress($address->mailbox, $address->host); - } - -} diff --git a/phpgwapi/inc/horde/Horde/iCalendar/vevent.php b/phpgwapi/inc/horde/Horde/iCalendar/vevent.php deleted file mode 100644 index 093ad0ecf2..0000000000 --- a/phpgwapi/inc/horde/Horde/iCalendar/vevent.php +++ /dev/null @@ -1,232 +0,0 @@ - - * @since Horde 3.0 - * @package Horde_iCalendar - */ -class Horde_iCalendar_vevent extends Horde_iCalendar { - - function getType() - { - return 'vEvent'; - } - - function exportvCalendar() - { - // Default values. - $requiredAttributes = array(); - $requiredAttributes['DTSTAMP'] = time(); - /* This is handled by the upper layers. - $requiredAttributes['UID'] = $this->_exportDateTime(time()) - . substr(str_pad(base_convert(microtime(), 10, 36), 16, uniqid(mt_rand()), STR_PAD_LEFT), -16) - . '@' . (isset($_SERVER['SERVER_NAME']) ? $_SERVER['SERVER_NAME'] : 'localhost'); - */ - - $method = !empty($this->_container) ? - $this->_container->getAttribute('METHOD') : 'PUBLISH'; - - switch ($method) { - case 'PUBLISH': - $requiredAttributes['DTSTART'] = time(); - $requiredAttributes['SUMMARY'] = ''; - break; - - case 'REQUEST': - $requiredAttributes['ATTENDEE'] = ''; - $requiredAttributes['DTSTART'] = time(); - $requiredAttributes['SUMMARY'] = ''; - break; - - case 'REPLY': - $requiredAttributes['ATTENDEE'] = ''; - break; - - case 'ADD': - $requiredAttributes['DTSTART'] = time(); - $requiredAttributes['SEQUENCE'] = 1; - $requiredAttributes['SUMMARY'] = ''; - break; - - case 'CANCEL': - $requiredAttributes['ATTENDEE'] = ''; - $requiredAttributes['SEQUENCE'] = 1; - break; - - case 'REFRESH': - $requiredAttributes['ATTENDEE'] = ''; - break; - } - - foreach ($requiredAttributes as $name => $default_value) { - if (is_a($this->getAttribute($name), 'PEAR_Error')) { - $this->setAttribute($name, $default_value); - } - } - - return parent::_exportvData('VEVENT'); - } - - /** - * Update the status of an attendee of an event. - * - * @param $email The email address of the attendee. - * @param $status The participant status to set. - * @param $fullname The full name of the participant to set. - */ - function updateAttendee($email, $status, $fullname = '') - { - foreach ($this->_attributes as $key => $attribute) { - if ($attribute['name'] == 'ATTENDEE' && - $attribute['value'] == 'mailto:' . $email) { - $this->_attributes[$key]['params']['PARTSTAT'] = $status; - if (!empty($fullname)) { - $this->_attributes[$key]['params']['CN'] = $fullname; - } - unset($this->_attributes[$key]['params']['RSVP']); - return; - } - } - $params = array('PARTSTAT' => $status); - if (!empty($fullname)) { - $params['CN'] = $fullname; - } - $this->setAttribute('ATTENDEE', 'mailto:' . $email, $params); - } - - /** - * Return the organizer display name or email. - * - * @return string The organizer name to display for this event. - */ - function organizerName() - { - $organizer = $this->getAttribute('ORGANIZER', true); - if (is_a($organizer, 'PEAR_Error')) { - return _("An unknown person"); - } - - if (isset($organizer[0]['CN'])) { - return $organizer[0]['CN']; - } - - $organizer = parse_url($this->getAttribute('ORGANIZER')); - - return $organizer['path']; - } - - /** - * Update this event with details from another event. - * - * @param Horde_iCalendar_vEvent $vevent The vEvent with latest details. - */ - function updateFromvEvent($vevent) - { - $newAttributes = $vevent->getAllAttributes(); - foreach ($newAttributes as $newAttribute) { - $currentValue = $this->getAttribute($newAttribute['name']); - if (is_a($currentValue, 'PEAR_error')) { - // Already exists so just add it. - $this->setAttribute($newAttribute['name'], - $newAttribute['value'], - $newAttribute['params']); - } else { - // Already exists so locate and modify. - $found = false; - - // Try matching the attribte name and value incase - // only the params changed (eg attendee updating - // status). - foreach ($this->_attributes as $id => $attr) { - if ($attr['name'] == $newAttribute['name'] && - $attr['value'] == $newAttribute['value']) { - // merge the params - foreach ($newAttribute['params'] as $param_id => $param_name) { - $this->_attributes[$id]['params'][$param_id] = $param_name; - } - $found = true; - break; - } - } - if (!$found) { - // Else match the first attribute with the same - // name (eg changing start time). - foreach ($this->_attributes as $id => $attr) { - if ($attr['name'] == $newAttribute['name']) { - $this->_attributes[$id]['value'] = $newAttribute['value']; - // Merge the params. - foreach ($newAttribute['params'] as $param_id => $param_name) { - $this->_attributes[$id]['params'][$param_id] = $param_name; - } - break; - } - } - } - } - } - } - - /** - * Update just the attendess of event with details from another - * event. - * - * @param Horde_iCalendar_vEvent $vevent The vEvent with latest details - */ - function updateAttendeesFromvEvent($vevent) - { - $newAttributes = $vevent->getAllAttributes(); - foreach ($newAttributes as $newAttribute) { - if ($newAttribute['name'] != 'ATTENDEE') { - continue; - } - $currentValue = $this->getAttribute($newAttribute['name']); - if (is_a($currentValue, 'PEAR_error')) { - // Already exists so just add it. - $this->setAttribute($newAttribute['name'], - $newAttribute['value'], - $newAttribute['params']); - } else { - // Already exists so locate and modify. - $found = false; - // Try matching the attribte name and value incase - // only the params changed (eg attendee updating - // status). - foreach ($this->_attributes as $id => $attr) { - if ($attr['name'] == $newAttribute['name'] && - $attr['value'] == $newAttribute['value']) { - // Merge the params. - foreach ($newAttribute['params'] as $param_id => $param_name) { - $this->_attributes[$id]['params'][$param_id] = $param_name; - } - $found = true; - break; - } - } - - if (!$found) { - // Else match the first attribute with the same - // name (eg changing start time). - foreach ($this->_attributes as $id => $attr) { - if ($attr['name'] == $newAttribute['name']) { - $this->_attributes[$id]['value'] = $newAttribute['value']; - // Merge the params. - foreach ($newAttribute['params'] as $param_id => $param_name) { - $this->_attributes[$id]['params'][$param_id] = $param_name; - } - break; - } - } - } - } - } - } - -} diff --git a/phpgwapi/inc/horde/Horde/iCalendar/vfreebusy.php b/phpgwapi/inc/horde/Horde/iCalendar/vfreebusy.php deleted file mode 100644 index 8811cfef0a..0000000000 --- a/phpgwapi/inc/horde/Horde/iCalendar/vfreebusy.php +++ /dev/null @@ -1,459 +0,0 @@ - - * @since Horde 3.0 - * @package Horde_iCalendar - */ -class Horde_iCalendar_vfreebusy extends Horde_iCalendar { - - var $_busyPeriods = array(); - var $_extraParams = array(); - - /** - * Returns the type of this calendar component. - * - * @return string The type of this component. - */ - function getType() - { - return 'vFreebusy'; - } - - /** - * Parses a string containing vFreebusy data. - * - * @param string $data The data to parse. - */ - function parsevCalendar($data, $type = null, $charset = null) - { - parent::parsevCalendar($data, 'VFREEBUSY', $charset); - - // Do something with all the busy periods. - foreach ($this->_attributes as $key => $attribute) { - if ($attribute['name'] != 'FREEBUSY') { - continue; - } - foreach ($attribute['values'] as $value) { - $params = isset($attribute['params']) - ? $attribute['params'] - : array(); - if (isset($value['duration'])) { - $this->addBusyPeriod('BUSY', $value['start'], null, - $value['duration'], $params); - } else { - $this->addBusyPeriod('BUSY', $value['start'], - $value['end'], null, $params); - } - } - unset($this->_attributes[$key]); - } - } - - /** - * Returns the component exported as string. - * - * @return string The exported vFreeBusy information according to the - * iCalender format specification. - */ - function exportvCalendar() - { - foreach ($this->_busyPeriods as $start => $end) { - $periods = array(array('start' => $start, 'end' => $end)); - $this->setAttribute('FREEBUSY', $periods, - isset($this->_extraParams[$start]) - ? $this->_extraParams[$start] : array()); - } - - $res = parent::_exportvData('VFREEBUSY'); - - foreach ($this->_attributes as $key => $attribute) { - if ($attribute['name'] == 'FREEBUSY') { - unset($this->_attributes[$key]); - } - } - - return $res; - } - - /** - * Returns a display name for this object. - * - * @return string A clear text name for displaying this object. - */ - function getName() - { - $name = ''; - $method = !empty($this->_container) ? - $this->_container->getAttribute('METHOD') : 'PUBLISH'; - - if (is_a($method, 'PEAR_Error') || $method == 'PUBLISH') { - $attr = 'ORGANIZER'; - } elseif ($method == 'REPLY') { - $attr = 'ATTENDEE'; - } - - $name = $this->getAttribute($attr, true); - if (!is_a($name, 'PEAR_Error') && isset($name[0]['CN'])) { - return $name[0]['CN']; - } - - $name = $this->getAttribute($attr); - if (is_a($name, 'PEAR_Error')) { - return ''; - } else { - $name = parse_url($name); - return $name['path']; - } - } - - /** - * Returns the email address for this object. - * - * @return string The email address of this object's owner. - */ - function getEmail() - { - $name = ''; - $method = !empty($this->_container) - ? $this->_container->getAttribute('METHOD') : 'PUBLISH'; - - if (is_a($method, 'PEAR_Error') || $method == 'PUBLISH') { - $attr = 'ORGANIZER'; - } elseif ($method == 'REPLY') { - $attr = 'ATTENDEE'; - } - - $name = $this->getAttribute($attr); - if (is_a($name, 'PEAR_Error')) { - return ''; - } else { - $name = parse_url($name); - return $name['path']; - } - } - - /** - * Returns the busy periods. - * - * @return array All busy periods. - */ - function getBusyPeriods() - { - return $this->_busyPeriods; - } - - /** - * Returns any additional freebusy parameters. - * - * @return array Additional parameters of the freebusy periods. - */ - function getExtraParams() - { - return $this->_extraParams; - } - - /** - * Returns all the free periods of time in a given period. - * - * @param integer $startStamp The start timestamp. - * @param integer $endStamp The end timestamp. - * - * @return array A hash with free time periods, the start times as the - * keys and the end times as the values. - */ - function getFreePeriods($startStamp, $endStamp) - { - $this->simplify(); - $periods = array(); - - // Check that we have data for some part of this period. - if ($this->getEnd() < $startStamp || $this->getStart() > $endStamp) { - return $periods; - } - - // Locate the first time in the requested period we have data for. - $nextstart = max($startStamp, $this->getStart()); - - // Check each busy period and add free periods in between. - foreach ($this->_busyPeriods as $start => $end) { - if ($start <= $endStamp && $end >= $nextstart) { - if ($nextstart <= $start) { - $periods[$nextstart] = min($start, $endStamp); - } - $nextstart = min($end, $endStamp); - } - } - - // If we didn't read the end of the requested period but still have - // data then mark as free to the end of the period or available data. - if ($nextstart < $endStamp && $nextstart < $this->getEnd()) { - $periods[$nextstart] = min($this->getEnd(), $endStamp); - } - - return $periods; - } - - /** - * Adds a busy period to the info. - * - * This function may throw away data in case you add a period with a start - * date that already exists. The longer of the two periods will be chosen - * (and all information associated with the shorter one will be removed). - * - * @param string $type The type of the period. Either 'FREE' or - * 'BUSY'; only 'BUSY' supported at the moment. - * @param integer $start The start timestamp of the period. - * @param integer $end The end timestamp of the period. - * @param integer $duration The duration of the period. If specified, the - * $end parameter will be ignored. - * @param array $extra Additional parameters for this busy period. - */ - function addBusyPeriod($type, $start, $end = null, $duration = null, - $extra = array()) - { - if ($type == 'FREE') { - // Make sure this period is not marked as busy. - return false; - } - - // Calculate the end time if duration was specified. - $tempEnd = is_null($duration) ? $end : $start + $duration; - - // Make sure the period length is always positive. - $end = max($start, $tempEnd); - $start = min($start, $tempEnd); - - if (isset($this->_busyPeriods[$start])) { - // Already a period starting at this time. Change the current - // period only if the new one is longer. This might be a problem - // if the callee assumes that there is no simplification going - // on. But since the periods are stored using the start time of - // the busy periods we have to throw away data here. - if ($end > $this->_busyPeriods[$start]) { - $this->_busyPeriods[$start] = $end; - $this->_extraParams[$start] = $extra; - } - } else { - // Add a new busy period. - $this->_busyPeriods[$start] = $end; - $this->_extraParams[$start] = $extra; - } - - return true; - } - - /** - * Returns the timestamp of the start of the time period this free busy - * information covers. - * - * @return integer A timestamp. - */ - function getStart() - { - if (!is_a($this->getAttribute('DTSTART'), 'PEAR_Error')) { - return $this->getAttribute('DTSTART'); - } elseif (count($this->_busyPeriods)) { - return min(array_keys($this->_busyPeriods)); - } else { - return false; - } - } - - /** - * Returns the timestamp of the end of the time period this free busy - * information covers. - * - * @return integer A timestamp. - */ - function getEnd() - { - if (!is_a($this->getAttribute('DTEND'), 'PEAR_Error')) { - return $this->getAttribute('DTEND'); - } elseif (count($this->_busyPeriods)) { - return max(array_values($this->_busyPeriods)); - } else { - return false; - } - } - - /** - * Merges the busy periods of another Horde_iCalendar_vfreebusy object - * into this one. - * - * This might lead to simplification no matter what you specify for the - * "simplify" flag since periods with the same start date will lead to the - * shorter period being removed (see addBusyPeriod). - * - * @param Horde_iCalendar_vfreebusy $freebusy A freebusy object. - * @param boolean $simplify If true, simplify() will - * called after the merge. - */ - function merge($freebusy, $simplify = true) - { - if (!is_a($freebusy, 'Horde_iCalendar_vfreebusy')) { - return false; - } - - $extra = $freebusy->getExtraParams(); - foreach ($freebusy->getBusyPeriods() as $start => $end) { - // This might simplify the busy periods without taking the - // "simplify" flag into account. - $this->addBusyPeriod('BUSY', $start, $end, null, - isset($extra[$start]) - ? $extra[$start] : array()); - } - - $thisattr = $this->getAttribute('DTSTART'); - $thatattr = $freebusy->getAttribute('DTSTART'); - if (is_a($thisattr, 'PEAR_Error') && !is_a($thatattr, 'PEAR_Error')) { - $this->setAttribute('DTSTART', $thatattr, array(), false); - } elseif (!is_a($thatattr, 'PEAR_Error')) { - if ($thatattr < $thisattr) { - $this->setAttribute('DTSTART', $thatattr, array(), false); - } - } - - $thisattr = $this->getAttribute('DTEND'); - $thatattr = $freebusy->getAttribute('DTEND'); - if (is_a($thisattr, 'PEAR_Error') && !is_a($thatattr, 'PEAR_Error')) { - $this->setAttribute('DTEND', $thatattr, array(), false); - } elseif (!is_a($thatattr, 'PEAR_Error')) { - if ($thatattr > $thisattr) { - $this->setAttribute('DTEND', $thatattr, array(), false); - } - } - - if ($simplify) { - $this->simplify(); - } - - return true; - } - - /** - * Removes all overlaps and simplifies the busy periods array as much as - * possible. - */ - function simplify() - { - $clean = false; - $busy = array($this->_busyPeriods, $this->_extraParams); - while (!$clean) { - $result = $this->_simplify($busy[0], $busy[1]); - $clean = $result === $busy; - $busy = $result; - } - - ksort($result[1], SORT_NUMERIC); - $this->_extraParams = $result[1]; - - ksort($result[0], SORT_NUMERIC); - $this->_busyPeriods = $result[0]; - } - - function _simplify($busyPeriods, $extraParams = array()) - { - $checked = array(); - $checkedExtra = array(); - $checkedEmpty = true; - - foreach ($busyPeriods as $start => $end) { - if ($checkedEmpty) { - $checked[$start] = $end; - $checkedExtra[$start] = isset($extraParams[$start]) - ? $extraParams[$start] : array(); - $checkedEmpty = false; - } else { - $added = false; - foreach ($checked as $testStart => $testEnd) { - // Replace old period if the new period lies around the - // old period. - if ($start <= $testStart && $end >= $testEnd) { - // Remove old period entry. - unset($checked[$testStart]); - unset($checkedExtra[$testStart]); - // Add replacing entry. - $checked[$start] = $end; - $checkedExtra[$start] = isset($extraParams[$start]) - ? $extraParams[$start] : array(); - $added = true; - } elseif ($start >= $testStart && $end <= $testEnd) { - // The new period lies fully within the old - // period. Just forget about it. - $added = true; - } elseif (($end <= $testEnd && $end >= $testStart) || - ($start >= $testStart && $start <= $testEnd)) { - // Now we are in trouble: Overlapping time periods. If - // we allow for additional parameters we cannot simply - // choose one of the two parameter sets. It's better - // to leave two separated time periods. - $extra = isset($extraParams[$start]) - ? $extraParams[$start] : array(); - $testExtra = isset($checkedExtra[$testStart]) - ? $checkedExtra[$testStart] : array(); - // Remove old period entry. - unset($checked[$testStart]); - unset($checkedExtra[$testStart]); - // We have two periods overlapping. Are their - // additional parameters the same or different? - $newStart = min($start, $testStart); - $newEnd = max($end, $testEnd); - if ($extra === $testExtra) { - // Both periods have the same information. So we - // can just merge. - $checked[$newStart] = $newEnd; - $checkedExtra[$newStart] = $extra; - } else { - // Extra parameters are different. Create one - // period at the beginning with the params of the - // first period and create a trailing period with - // the params of the second period. The break - // point will be the end of the first period. - $break = min($end, $testEnd); - $checked[$newStart] = $break; - $checkedExtra[$newStart] = - isset($extraParams[$newStart]) - ? $extraParams[$newStart] : array(); - $checked[$break] = $newEnd; - $highStart = max($start, $testStart); - $checkedExtra[$break] = - isset($extraParams[$highStart]) - ? $extraParams[$highStart] : array(); - - // Ensure we also have the extra data in the - // extraParams. - $extraParams[$break] = - isset($extraParams[$highStart]) - ? $extraParams[$highStart] : array(); - } - $added = true; - } - - if ($added) { - break; - } - } - - if (!$added) { - $checked[$start] = $end; - $checkedExtra[$start] = isset($extraParams[$start]) - ? $extraParams[$start] : array(); - } - } - } - - return array($checked, $checkedExtra); - } - -} diff --git a/phpgwapi/inc/horde/Horde/iCalendar/vjournal.php b/phpgwapi/inc/horde/Horde/iCalendar/vjournal.php deleted file mode 100644 index 2ad56e5a5f..0000000000 --- a/phpgwapi/inc/horde/Horde/iCalendar/vjournal.php +++ /dev/null @@ -1,28 +0,0 @@ - - * @since Horde 3.0 - * @package Horde_iCalendar - */ -class Horde_iCalendar_vjournal extends Horde_iCalendar { - - function getType() - { - return 'vJournal'; - } - - function exportvCalendar() - { - return parent::_exportvData('VJOURNAL'); - } - -} diff --git a/phpgwapi/inc/horde/Horde/iCalendar/vnote.php b/phpgwapi/inc/horde/Horde/iCalendar/vnote.php deleted file mode 100644 index eb625dbaf4..0000000000 --- a/phpgwapi/inc/horde/Horde/iCalendar/vnote.php +++ /dev/null @@ -1,49 +0,0 @@ - - * @author Karsten Fourmont - * @package Horde_iCalendar - */ -class Horde_iCalendar_vnote extends Horde_iCalendar { - - function Horde_iCalendar_vnote($version = '1.1') - { - return parent::Horde_iCalendar($version); - } - - function getType() - { - return 'vNote'; - } - - /** - * Unlike vevent and vtodo, a vnote is normally not enclosed in an - * iCalendar container. (BEGIN..END) - */ - function exportvCalendar() - { - $requiredAttributes['BODY'] = ''; - $requiredAttributes['VERSION'] = '1.1'; - - foreach ($requiredAttributes as $name => $default_value) { - if (is_a($this->getattribute($name), 'PEAR_Error')) { - $this->setAttribute($name, $default_value); - } - } - - return $this->_exportvData('VNOTE'); - } - -} diff --git a/phpgwapi/inc/horde/Horde/iCalendar/vtimezone.php b/phpgwapi/inc/horde/Horde/iCalendar/vtimezone.php deleted file mode 100644 index 197e0b30f5..0000000000 --- a/phpgwapi/inc/horde/Horde/iCalendar/vtimezone.php +++ /dev/null @@ -1,254 +0,0 @@ - - * @since Horde 3.0 - * @package Horde_iCalendar - * @changes 2010/02/26 Joerg Lehrke : Add RDATE support (for KDE 4.x) - */ -class Horde_iCalendar_vtimezone extends Horde_iCalendar { - - function getType() - { - return 'vTimeZone'; - } - - function exportvCalendar() - { - return parent::_exportvData('VTIMEZONE'); - } - - /** - * Parse child components of the vTimezone component. Returns an - * array with the exact time of the time change as well as the - * 'from' and 'to' offsets around the change. Time is arbitrarily - * based on UTC for comparison. - */ - function parseChild(&$child, $year) - { - // Make sure 'time' key is first for sort(). - $result['time'] = 0; - $rrule_interval = 0; // 0 undefined, 1 yearly, 12 monthly - - $t = $child->getAttribute('TZOFFSETFROM'); - if (is_a($t, 'PEAR_Error')) { - return false; - } - $result['from'] = ($t['hour'] * 60 * 60 + $t['minute'] * 60) * ($t['ahead'] ? 1 : -1); - - $t = $child->getAttribute('TZOFFSETTO'); - if (is_a($t, 'PEAR_Error')) { - return false; - } - $result['to'] = ($t['hour'] * 60 * 60 + $t['minute'] * 60) * ($t['ahead'] ? 1 : -1); - - $switch_time = $child->getAttribute('DTSTART'); - if (is_a($switch_time, 'PEAR_Error')) { - return false; - } - - $rdates = $child->getAttribute('RDATE'); - if (!is_a($rdates, 'PEAR_Error')) { - foreach ($rdates as $rdate) { - $switch_time = $switch_time['value']; - $switch_year = date("Y", $switch_time); - if ($switch_year == $year) { - $t = getdate($switch_time); - $result['time'] = @gmmktime($t['hours'], $t['minutes'], $t['seconds'], - $t['mon'], $t['mday'], $t['year']); - return $result; - } - } - } - - $rrules = $child->getAttribute('RRULE'); - if (is_a($rrules, 'PEAR_Error')) { - if (!is_int($switch_time)) { - return false; - } - // Convert this timestamp from local time to UTC for - // comparison (All dates are compared as if they are UTC). - $t = getdate($switch_time); - $result['time'] = @gmmktime($t['hours'], $t['minutes'], $t['seconds'], - $t['mon'], $t['mday'], $t['year']); - return $result; - } - - $switch_year = date("Y", $switch_time); - if ($switch_year > $year) { - return false; - } - - $rrules = explode(';', $rrules); - foreach ($rrules as $rrule) { - $t = explode('=', $rrule); - switch ($t[0]) { - case 'FREQ': - switch($t[1]) { - case 'YEARLY': - if ($rrule_interval == 12) { - return false; - } - $rrule_interval = 1; - break; - case 'MONTHLY': - if ($rrule_interval == 1) { - return false; - } - $rrule_interval = 12; - break; - default: - return false; - } - break; - - case 'INTERVAL': - if ($rrule_interval && $t[1] != $rrule_interval) { - return false; - } - $rrule_interval = intval($t[1]); - if ($rrule_interval != 1 && $rrule_interval != 12) { - return false; - } - break; - - case 'COUNT': - if ($switch_year + intval($t[1]) < intval($year)) { - return false; - } - break; - - case 'BYMONTH': - $month = intval($t[1]); - break; - - case 'BYDAY': - $len = strspn($t[1], '1234567890-+'); - if ($len == 0) { - return false; - } - $weekday = substr($t[1], $len); - $weekdays = array( - 'SU' => 0, - 'MO' => 1, - 'TU' => 2, - 'WE' => 3, - 'TH' => 4, - 'FR' => 5, - 'SA' => 6 - ); - $weekday = $weekdays[$weekday]; - $which = intval(substr($t[1], 0, $len)); - break; - - case 'UNTIL': - if (intval($year) > intval(substr($t[1], 0, 4))) { - return false; - } - break; - } - } - - if ($rrule_interval == 12) { - $month = date("n", $switch_time); - } - - if (empty($month) || !isset($weekday)) { - return false; - } - - if (is_int($switch_time)) { - // Was stored as localtime. - $switch_time = strftime('%H:%M:%S', $switch_time); - $switch_time = explode(':', $switch_time); - } else { - $switch_time = explode('T', $switch_time); - if (count($switch_time) != 2) { - return false; - } - $switch_time[0] = substr($switch_time[1], 0, 2); - $switch_time[2] = substr($switch_time[1], 4, 2); - $switch_time[1] = substr($switch_time[1], 2, 2); - } - - // Get the timestamp for the first day of $month. - $when = gmmktime($switch_time[0], $switch_time[1], $switch_time[2], - $month, 1, $year); - // Get the day of the week for the first day of $month. - $first_of_month_weekday = intval(gmstrftime('%w', $when)); - - // Go to the first $weekday before first day of $month. - if ($weekday >= $first_of_month_weekday) { - $weekday -= 7; - } - $when -= ($first_of_month_weekday - $weekday) * 60 * 60 * 24; - - // If going backwards go to the first $weekday after last day - // of $month. - if ($which < 0) { - do { - $when += 60*60*24*7; - } while (intval(gmstrftime('%m', $when)) == $month); - } - - // Calculate $weekday number $which. - $when += $which * 60 * 60 * 24 * 7; - - $result['time'] = $when; - - return $result; - } - -} - -/** - * @package Horde_iCalendar - */ -class Horde_iCalendar_standard extends Horde_iCalendar { - - function getType() - { - return 'standard'; - } - - function parsevCalendar($data) - { - parent::parsevCalendar($data, 'STANDARD'); - } - - function exportvCalendar() - { - return parent::_exportvData('STANDARD'); - } - -} - -/** - * @package Horde_iCalendar - */ -class Horde_iCalendar_daylight extends Horde_iCalendar { - - function getType() - { - return 'daylight'; - } - - function parsevCalendar($data) - { - parent::parsevCalendar($data, 'DAYLIGHT'); - } - - function exportvCalendar() - { - return parent::_exportvData('DAYLIGHT'); - } - -} diff --git a/phpgwapi/inc/horde/Horde/iCalendar/vtodo.php b/phpgwapi/inc/horde/Horde/iCalendar/vtodo.php deleted file mode 100644 index a7cce95dd0..0000000000 --- a/phpgwapi/inc/horde/Horde/iCalendar/vtodo.php +++ /dev/null @@ -1,84 +0,0 @@ - - * @since Horde 3.0 - * @package Horde_iCalendar - */ -class Horde_iCalendar_vtodo extends Horde_iCalendar { - - function getType() - { - return 'vTodo'; - } - - function exportvCalendar() - { - return parent::_exportvData('VTODO'); - } - - /** - * Convert this todo to an array of attributes. - * - * @return array Array containing the details of the todo in a hash - * as used by Horde applications. - */ - function toArray() - { - $todo = array(); - - $name = $this->getAttribute('SUMMARY'); - if (!is_array($name) && !is_a($name, 'PEAR_Error')) { - $todo['name'] = $name; - } - $desc = $this->getAttribute('DESCRIPTION'); - if (!is_array($desc) && !is_a($desc, 'PEAR_Error')) { - $todo['desc'] = $desc; - } - - $priority = $this->getAttribute('PRIORITY'); - if (!is_array($priority) && !is_a($priority, 'PEAR_Error')) { - $todo['priority'] = $priority; - } - - $due = $this->getAttribute('DTSTAMP'); - if (!is_array($due) && !is_a($due, 'PEAR_Error')) { - $todo['due'] = $due; - } - - return $todo; - } - - /** - * Set the attributes for this todo item from an array. - * - * @param array $todo Array containing the details of the todo in - * the same format that toArray() exports. - */ - function fromArray($todo) - { - if (isset($todo['name'])) { - $this->setAttribute('SUMMARY', $todo['name']); - } - if (isset($todo['desc'])) { - $this->setAttribute('DESCRIPTION', $todo['desc']); - } - - if (isset($todo['priority'])) { - $this->setAttribute('PRIORITY', $todo['priority']); - } - - if (isset($todo['due'])) { - $this->setAttribute('DTSTAMP', $todo['due']); - } - } - -} diff --git a/phpgwapi/inc/horde/XML/WBXML.php b/phpgwapi/inc/horde/XML/WBXML.php deleted file mode 100644 index bbf8ac2bf0..0000000000 --- a/phpgwapi/inc/horde/XML/WBXML.php +++ /dev/null @@ -1,300 +0,0 @@ - - * @package XML_WBXML - */ -class XML_WBXML { - - /** - * Decoding Multi-byte Integers from Section 5.1 - * - * Use long because it is unsigned. - */ - function MBUInt32ToInt($in, &$pos) - { - $val = 0; - - do { - $b = ord($in[$pos++]); - $val <<= 7; // Bitshift left 7 bits. - $val += ($b & 127); - } while (($b & 128) != 0); - - return $val; - } - - /** - * Encoding Multi-byte Integers from Section 5.1 - */ - function intToMBUInt32(&$out, $i) - { - if ($i > 268435455) { - $bytes0 = 0 | XML_WBXML::getBits(0, $i); - $bytes1 = 128 | XML_WBXML::getBits(1, $i); - $bytes2 = 128 | XML_WBXML::getBits(2, $i); - $bytes3 = 128 | XML_WBXML::getBits(3, $i); - $bytes4 = 128 | XML_WBXML::getBits(4, $i); - - $out .= chr($bytes4) . chr($bytes3) . chr($bytes2) . chr($bytes1) . chr($bytes0); - } elseif ($i > 2097151) { - $bytes0 = 0 | XML_WBXML::getBits(0, $i); - $bytes1 = 128 | XML_WBXML::getBits(1, $i); - $bytes2 = 128 | XML_WBXML::getBits(2, $i); - $bytes3 = 128 | XML_WBXML::getBits(3, $i); - - $out .= chr($bytes3) . chr($bytes2) . chr($bytes1) . chr($bytes0); - } elseif ($i > 16383) { - $bytes0 = 0 | XML_WBXML::getBits(0, $i); - $bytes1 = 128 | XML_WBXML::getBits(1, $i); - $bytes2 = 128 | XML_WBXML::getBits(2, $i); - - $out .= chr($bytes2) . chr($bytes1) . chr($bytes0); - } elseif ($i > 127) { - $bytes0 = 0 | XML_WBXML::getBits(0, $i); - $bytes1 = 128 | XML_WBXML::getBits(1, $i); - - $out .= chr($bytes1) . chr($bytes0); - } else { - $bytes0 = 0 | XML_WBXML::getBits(0, $i); - - $out .= chr($bytes0); - } - } - - function getBits($num, $l) - { - switch ($num) { - case 0: - return $l & 127; // 0x7F - - case 1: - return ($l >> 7) & 127; // 0x7F - - case 2: - return ($l >> 14) & 127; // 0x7F - - case 3: - return ($l >> 21) & 127; // 0x7F - - case 4: - return ($l >> 28) & 127; // 0x7F - } - - return 0; - } - - function getDPIString($i) - { - /** - * ADD CHAPTER - */ - $DPIString = array(2 => DPI_DTD_WML_1_0, - 3 => DPI_DTD_WTA_1_0, - 4 => DPI_DTD_WML_1_1, - 5 => DPI_DTD_SI_1_1, - 6 => DPI_DTD_SL_1_0, - 7 => DPI_DTD_CO_1_0, - 8 => DPI_DTD_CHANNEL_1_1, - 9 => DPI_DTD_WML_1_2, - 10 => DPI_DTD_WML_1_3, - 11 => DPI_DTD_PROV_1_0, - 12 => DPI_DTD_WTA_WML_1_2, - 13 => DPI_DTD_CHANNEL_1_2, - - // Not all SyncML clients know this, so we - // should use the string table. - // 0xFD1 => DPI_DTD_SYNCML_1_1, - // These codes are taken from libwbxml wbxml_tables.h: - 4049 => DPI_DTD_SYNCML_1_0, // 0x0fd1 - 4050 => DPI_DTD_DEVINF_1_0, // 0x0fd2 - 4051 => DPI_DTD_SYNCML_1_1, // 0x0fd3 - 4052 => DPI_DTD_DEVINF_1_1, // 0x0fd4 - 4609 => DPI_DTD_SYNCML_1_2, // 0x1201 - //@todo: verify this: - 4611 => DPI_DTD_DEVINF_1_2 // 0x1203 -// taken from libxml but might be wrong: -// 4610 => DPI_DTD_DEVINF_1_2, // 0x1202 -// 4611 => DPI_DTD_METINF_1_2 // 0x1203 - ); - return isset($DPIString[$i]) ? $DPIString[$i] : null; - } - - function getDPIInt($dpi) - { - /** - * ADD CHAPTER - */ - $DPIInt = array(DPI_DTD_WML_1_0 => 2, - DPI_DTD_WTA_1_0 => 3, - DPI_DTD_WML_1_1 => 4, - DPI_DTD_SI_1_1 => 5, - DPI_DTD_SL_1_0 => 6, - DPI_DTD_CO_1_0 => 7, - DPI_DTD_CHANNEL_1_1 => 8, - DPI_DTD_WML_1_2 => 9, - DPI_DTD_WML_1_3 => 10, - DPI_DTD_PROV_1_0 => 11, - DPI_DTD_WTA_WML_1_2 => 12, - DPI_DTD_CHANNEL_1_2 => 13, - - // Not all SyncML clients know this, so maybe we - // should use the string table. - // These codes are taken from libwbxml wbxml_tables.h: - DPI_DTD_SYNCML_1_0 => 4049, - DPI_DTD_DEVINF_1_0 => 4050, - DPI_DTD_SYNCML_1_1 => 4051, - DPI_DTD_DEVINF_1_1 => 4052, - DPI_DTD_SYNCML_1_2 => 4609, // 0x1201 -// DPI_DTD_DEVINF_1_2 => 4610, // 0x1202 -// DPI_DTD_METINF_1_2 => 4611 // 0x1203 - //@todo: verify this - DPI_DTD_DEVINF_1_2 => 4611 // 0x1203 - // DPI_DTD_SYNCML_1_1 => 0xFD1, - // DPI_DTD_DEVINF_1_1 => 0xFD2, - ); - - return isset($DPIInt[$dpi]) ? $DPIInt[$dpi] : 0; - } - - /** - * Returns the character encoding. - * only default character encodings from J2SE are supported - * from http://www.iana.org/assignments/character-sets - * and http://java.sun.com/j2se/1.4.2/docs/api/java/nio/charset/Charset.html - */ - function getCharsetString($cs) - { - /** - * From http://www.iana.org/assignments/character-sets - */ - $charsetString = array(3 => 'US-ASCII', - 4 => 'ISO-8859-1', - 106 => 'UTF-8', - 1013 => 'UTF-16BE', - 1014 => 'UTF-16LE', - 1015 => 'UTF-16'); - - return isset($charsetString[$cs]) ? $charsetString[$cs] : null; - } - - /** - * Returns the character encoding. - * - * Only default character encodings from J2SE are supported. - * - * From http://www.iana.org/assignments/character-sets and - * http://java.sun.com/j2se/1.4.2/docs/api/java/nio/charset/Charset.html - */ - function getCharsetInt($cs) - { - /** - * From http://www.iana.org/assignments/character-sets - */ - $charsetInt = array('US-ASCII' => 3, - 'ISO-8859-1' => 4, - 'UTF-8' => 106, - 'UTF-16BE' => 1013, - 'UTF-16LE' => 1014, - 'UTF-16' => 1015); - - return isset($charsetInt[$cs]) ? $charsetInt[$cs] : null; - } - -} - -/** - * @package XML_WBXML - */ -class XML_WBXML_HashTable { - - var $_h; - - function set($k, $v) - { - $this->_h[$k] = $v; - } - - function get($k) - { - return isset($this->_h[$k]) ? $this->_h[$k] : null; - } - -} diff --git a/phpgwapi/inc/horde/XML/WBXML/ContentHandler.php b/phpgwapi/inc/horde/XML/WBXML/ContentHandler.php deleted file mode 100644 index 0e1ff72b5f..0000000000 --- a/phpgwapi/inc/horde/XML/WBXML/ContentHandler.php +++ /dev/null @@ -1,167 +0,0 @@ - - * @package XML_WBXML - */ -class XML_WBXML_ContentHandler { - - var $_currentUri; - var $_output = ''; - - var $_opaqueHandler; - - /** - * Charset. - */ - var $_charset = 'UTF-8'; - - /** - * WBXML Version. - * 0, 1 or 2 supported - */ - var $_wbxmlVersion = 2; - - function XML_WBXML_ContentHandler() - { - $this->_currentUri = new XML_WBXML_LifoQueue(); - } - - /** - */ - function raiseError($error) - { - if (!class_exists('PEAR')) { - require 'PEAR.php'; - } - return PEAR::raiseError($error); - } - - function getCharsetStr() - { - return $this->_charset; - } - - function setCharset($cs) - { - $this->_charset = $cs; - } - - function getVersion() - { - return $this->_wbxmlVersion; - } - - function setVersion($v) - { - $this->_wbxmlVersion = $v; - } - - function getOutput() - { - return $this->_output; - } - - function getOutputSize() - { - return strlen($this->_output); - } - - function startElement($uri, $element, $attrs = array()) - { - $this->_output .= '<' . $element; - - $currentUri = $this->_currentUri->top(); - - if (((!$currentUri) || ($currentUri != $uri)) && $uri) { - $this->_output .= ' xmlns="' . $uri . '"'; - } - - $this->_currentUri->push($uri); - - foreach ($attrs as $attr) { - $this->_output .= ' ' . $attr['attribute'] . '="' . $attr['value'] . '"'; - } - - $this->_output .= '>'; - } - - function endElement($uri, $element) - { - $this->_output .= ''; - - $this->_currentUri->pop(); - } - - function characters($str) - { - $this->_output .= $str; - } - - function opaque($o) - { - $this->_output .= $o; - } - - function setOpaqueHandler($opaqueHandler) - { - $this->_opaqueHandler = $opaqueHandler; - } - - function removeOpaqueHandler() - { - unset($this->_opaqueHandler); - } - - function createSubHandler() - { - $name = get_class($this); // clone current class - $sh = new $name(); - $sh->setCharset($this->getCharsetStr()); - $sh->setVersion($this->getVersion()); - return $sh; - } - -} - -class XML_WBXML_LifoQueue { - - var $_queue = array(); - - function XML_WBXML_LifoQueue() - { - } - - function push($obj) - { - $this->_queue[] = $obj; - } - - function pop() - { - if (count($this->_queue)) { - return array_pop($this->_queue); - } else { - return null; - } - } - - function top() - { - if ($count = count($this->_queue)) { - return $this->_queue[$count - 1]; - } else { - return null; - } - } - -} diff --git a/phpgwapi/inc/horde/XML/WBXML/DTD.php b/phpgwapi/inc/horde/XML/WBXML/DTD.php deleted file mode 100644 index 39c336ea50..0000000000 --- a/phpgwapi/inc/horde/XML/WBXML/DTD.php +++ /dev/null @@ -1,156 +0,0 @@ - - * @package XML_WBXML - */ -class XML_WBXML_DTD { - - var $version; - var $intTags; - var $intAttributes; - var $strTags; - var $strAttributes; - var $intCodePages; - var $strCodePages; - var $strCodePagesURI; - var $URI; - var $XMLNS; - var $DPI; - - function XML_WBXML_DTD($v) - { - $this->version = $v; - $this->init(); - } - - function init() - { - } - - function setAttribute($intAttribute, $strAttribute) - { - $this->strAttributes[$strAttribute] = $intAttribute; - $this->intAttributes[$intAttribute] = $strAttribute; - } - - function setTag($intTag, $strTag) - { - $this->strTags[$strTag] = $intTag; - $this->intTags[$intTag] = $strTag; - } - - function setCodePage($intCodePage, $strCodePage, $strCodePageURI) - { - $this->strCodePagesURI[$strCodePageURI] = $intCodePage; - $this->strCodePages[$strCodePage] = $intCodePage; - $this->intCodePages[$intCodePage] = $strCodePage; - } - - function toTagStr($tag) - { - return isset($this->intTags[$tag]) ? $this->intTags[$tag] : false; - } - - function toAttributeStr($attribute) - { - return isset($this->intTags[$attribute]) ? $this->intTags[$attribute] : false; - } - - function toCodePageStr($codePage) - { - return isset($this->intCodePages[$codePage]) ? $this->intCodePages[$codePage] : false; - } - - function toTagInt($tag) - { - return isset($this->strTags[$tag]) ? $this->strTags[$tag] : false; - } - - function toAttributeInt($attribute) - { - return isset($this->strAttributes[$attribute]) ? $this->strAttributes[$attribute] : false; - } - - function toCodePageInt($codePage) - { - return isset($this->strCodePages[$codePage]) ? $this->strCodePages[$codePage] : false; - } - - function toCodePageURI($uri) - { - $uri = strtolower($uri); - if (!isset($this->strCodePagesURI[$uri])) { - //Horde::logMessage("WBXML unable to find codepage for $uri!", __FILE__, __LINE__, PEAR_LOG_DEBUG); - //die("unable to find codepage for $uri!\n"); - } - - $ret = isset($this->strCodePagesURI[$uri]) ? $this->strCodePagesURI[$uri] : false; - - return $ret; - } - - /** - * Getter for property version. - * @return Value of property version. - */ - function getVersion() - { - return $this->version; - } - - /** - * Setter for property version. - * @param integer $v New value of property version. - */ - function setVersion($v) - { - $this->version = $v; - } - - /** - * Getter for property URI. - * @return Value of property URI. - */ - function getURI() - { - return $this->URI; - } - - /** - * Setter for property URI. - * @param string $u New value of property URI. - */ - function setURI($u) - { - $this->URI = $u; - } - - /** - * Getter for property DPI. - * @return Value of property DPI. - */ - function getDPI() - { - return $this->DPI; - } - - /** - * Setter for property DPI. - * @param DPI New value of property DPI. - */ - function setDPI($d) - { - $this->DPI = $d; - } - -} diff --git a/phpgwapi/inc/horde/XML/WBXML/DTD/SyncML.php b/phpgwapi/inc/horde/XML/WBXML/DTD/SyncML.php deleted file mode 100644 index bbee83f931..0000000000 --- a/phpgwapi/inc/horde/XML/WBXML/DTD/SyncML.php +++ /dev/null @@ -1,102 +0,0 @@ - - * @package XML_WBXML - */ -class XML_WBXML_DTD_SyncML extends XML_WBXML_DTD { - - function init() - { - /* this code table has been extracted from libwbxml - * (see http://libwbxml.aymerick.com/) by using - * - * grep '\"[^\"]*\", *0x.., 0x.. },' wbxml_tables.c - * | sed -e 's#^.*\"\([^\"]*\)\", *\(0x..\), \(0x..\) },.*$# \$this->setTag\(\3, \"\1\"\); // \2#g' - */ - - $this->setTag(0x05, "Add"); // 0x00 - $this->setTag(0x06, "Alert"); // 0x00 - $this->setTag(0x07, "Archive"); // 0x00 - $this->setTag(0x08, "Atomic"); // 0x00 - $this->setTag(0x09, "Chal"); // 0x00 - $this->setTag(0x0a, "Cmd"); // 0x00 - $this->setTag(0x0b, "CmdID"); // 0x00 - $this->setTag(0x0c, "CmdRef"); // 0x00 - $this->setTag(0x0d, "Copy"); // 0x00 - $this->setTag(0x0e, "Cred"); // 0x00 - $this->setTag(0x0f, "Data"); // 0x00 - $this->setTag(0x10, "Delete"); // 0x00 - $this->setTag(0x11, "Exec"); // 0x00 - $this->setTag(0x12, "Final"); // 0x00 - $this->setTag(0x13, "Get"); // 0x00 - $this->setTag(0x14, "Item"); // 0x00 - $this->setTag(0x15, "Lang"); // 0x00 - $this->setTag(0x16, "LocName"); // 0x00 - $this->setTag(0x17, "LocURI"); // 0x00 - $this->setTag(0x18, "Map"); // 0x00 - $this->setTag(0x19, "MapItem"); // 0x00 - $this->setTag(0x1a, "Meta"); // 0x00 - $this->setTag(0x1b, "MsgID"); // 0x00 - $this->setTag(0x1c, "MsgRef"); // 0x00 - $this->setTag(0x1d, "NoResp"); // 0x00 - $this->setTag(0x1e, "NoResults"); // 0x00 - $this->setTag(0x1f, "Put"); // 0x00 - $this->setTag(0x20, "Replace"); // 0x00 - $this->setTag(0x21, "RespURI"); // 0x00 - $this->setTag(0x22, "Results"); // 0x00 - $this->setTag(0x23, "Search"); // 0x00 - $this->setTag(0x24, "Sequence"); // 0x00 - $this->setTag(0x25, "SessionID"); // 0x00 - $this->setTag(0x26, "SftDel"); // 0x00 - $this->setTag(0x27, "Source"); // 0x00 - $this->setTag(0x28, "SourceRef"); // 0x00 - $this->setTag(0x29, "Status"); // 0x00 - $this->setTag(0x2a, "Sync"); // 0x00 - $this->setTag(0x2b, "SyncBody"); // 0x00 - $this->setTag(0x2c, "SyncHdr"); // 0x00 - $this->setTag(0x2d, "SyncML"); // 0x00 - $this->setTag(0x2e, "Target"); // 0x00 - $this->setTag(0x2f, "TargetRef"); // 0x00 - $this->setTag(0x30, "Reserved for future use"); // 0x00 - $this->setTag(0x31, "VerDTD"); // 0x00 - $this->setTag(0x32, "VerProto"); // 0x00 - $this->setTag(0x33, "NumberOfChanges"); // 0x00 - $this->setTag(0x34, "MoreData"); // 0x00 - $this->setTag(0x35, "Field"); // 0x00 - $this->setTag(0x36, "Filter"); // 0x00 - $this->setTag(0x37, "Record"); // 0x00 - $this->setTag(0x38, "FilterType"); // 0x00 - $this->setTag(0x39, "SourceParent"); // 0x00 - $this->setTag(0x3a, "TargetParent"); // 0x00 - $this->setTag(0x3b, "Move"); // 0x00 - $this->setTag(0x3c, "Correlator"); // 0x00 - - if ($this->version == 1) { - $this->setCodePage(0, DPI_DTD_SYNCML_1_1, 'syncml:syncml1.1'); - $this->setCodePage(1, DPI_DTD_METINF_1_1, 'syncml:metinf1.1'); - $this->setURI('syncml:syncml1.1'); - } elseif ($this->version == 2) { - $this->setCodePage(0, DPI_DTD_SYNCML_1_2, 'syncml:syncml1.2'); - $this->setCodePage(1, DPI_DTD_METINF_1_2, 'syncml:metinf1.2'); - $this->setURI('syncml:syncml1.2'); - } else { - $this->setCodePage(0, DPI_DTD_SYNCML_1_0, 'syncml:syncml1.0'); - $this->setCodePage(1, DPI_DTD_METINF_1_0, 'syncml:metinf1.0'); - $this->setURI('syncml:syncml1.0'); - } - } - -} diff --git a/phpgwapi/inc/horde/XML/WBXML/DTD/SyncMLDevInf.php b/phpgwapi/inc/horde/XML/WBXML/DTD/SyncMLDevInf.php deleted file mode 100644 index 6cb83c88b7..0000000000 --- a/phpgwapi/inc/horde/XML/WBXML/DTD/SyncMLDevInf.php +++ /dev/null @@ -1,92 +0,0 @@ - - * @package XML_WBXML - */ -class XML_WBXML_DTD_SyncMLDevInf extends XML_WBXML_DTD { - - function init() - { - /* this code table has been extracted from libwbxml - * (see http://libwbxml.aymerick.com/) by using - * - * grep '\"[^\"]*\", *0x.., 0x.. },' wbxml_tables.c - * | sed -e 's#^.*\"\([^\"]*\)\", *\(0x..\), \(0x..\) },.*$# \$this->setTag\(\3, \"\1\"\); // \2#g' - */ - - #Horde::logMessage("XML_WBXML_DTD_SyncMLDevInf version=" . $this->version, __FILE__, __LINE__, PEAR_LOG_DEBUG); - - $this->setTag(0x05, "CTCap"); // 0x00 - $this->setTag(0x06, "CTType"); // 0x00 - $this->setTag(0x07, "DataStore"); // 0x00 - $this->setTag(0x08, "DataType"); // 0x00 - $this->setTag(0x09, "DevID"); // 0x00 - $this->setTag(0x0a, "DevInf"); // 0x00 - $this->setTag(0x0b, "DevTyp"); // 0x00 - $this->setTag(0x0c, "DisplayName"); // 0x00 - $this->setTag(0x0d, "DSMem"); // 0x00 - $this->setTag(0x0e, "Ext"); // 0x00 - $this->setTag(0x0f, "FwV"); // 0x00 - $this->setTag(0x10, "HwV"); // 0x00 - $this->setTag(0x11, "Man"); // 0x00 - $this->setTag(0x12, "MaxGUIDSize"); // 0x00 - $this->setTag(0x13, "MaxID"); // 0x00 - $this->setTag(0x14, "MaxMem"); // 0x00 - $this->setTag(0x15, "Mod"); // 0x00 - $this->setTag(0x16, "OEM"); // 0x00 - $this->setTag(0x17, "ParamName"); // 0x00 - $this->setTag(0x18, "PropName"); // 0x00 - $this->setTag(0x19, "Rx"); // 0x00 - $this->setTag(0x1a, "Rx-Pref"); // 0x00 - $this->setTag(0x1b, "SharedMem"); // 0x00 - $this->setTag(0x1c, "Size"); // 0x00 - $this->setTag(0x1d, "SourceRef"); // 0x00 - $this->setTag(0x1e, "SwV"); // 0x00 - $this->setTag(0x1f, "SyncCap"); // 0x00 - $this->setTag(0x20, "SyncType"); // 0x00 - $this->setTag(0x21, "Tx"); // 0x00 - $this->setTag(0x22, "Tx-Pref"); // 0x00 - $this->setTag(0x23, "ValEnum"); // 0x00 - $this->setTag(0x24, "VerCT"); // 0x00 - $this->setTag(0x25, "VerDTD"); // 0x00 - $this->setTag(0x26, "XNam"); // 0x00 - $this->setTag(0x27, "XVal"); // 0x00 - $this->setTag(0x28, "UTC"); // 0x00 - $this->setTag(0x29, "SupportNumberOfChanges"); // 0x00 - $this->setTag(0x2a, "SupportLargeObjs"); // 0x00 - $this->setTag(0x2b, "Property"); // 0x00 - $this->setTag(0x2c, "PropParam"); // 0x00 - $this->setTag(0x2d, "MaxOccur"); // 0x00 - $this->setTag(0x2e, "NoTruncate"); // 0x00 - $this->setTag(0x30, "Filter-Rx"); // 0x00 - $this->setTag(0x31, "FilterCap"); // 0x00 - $this->setTag(0x32, "FilterKeyword"); // 0x00 - $this->setTag(0x33, "FieldLevel"); // 0x00 - $this->setTag(0x34, "SupportHierarchicalSync"); // 0x00 - - if ($this->version == 1) { - $this->setCodePage(0, DPI_DTD_DEVINF_1_1, 'syncml:devinf1.1'); - $this->setURI('syncml:devinf1.1'); - } elseif ($this->version == 2) { - $this->setCodePage(0, DPI_DTD_DEVINF_1_2, 'syncml:devinf1.2'); - $this->setURI('syncml:devinf1.2'); - } else { - $this->setCodePage(0, DPI_DTD_DEVINF_1_0, 'syncml:devinf1.0'); - $this->setURI('syncml:devinf1.0'); - } - } - -} diff --git a/phpgwapi/inc/horde/XML/WBXML/DTD/SyncMLMetInf.php b/phpgwapi/inc/horde/XML/WBXML/DTD/SyncMLMetInf.php deleted file mode 100644 index 650ba74189..0000000000 --- a/phpgwapi/inc/horde/XML/WBXML/DTD/SyncMLMetInf.php +++ /dev/null @@ -1,66 +0,0 @@ - - * @package XML_WBXML - */ -class XML_WBXML_DTD_SyncMLMetInf extends XML_WBXML_DTD { - - function init() - { - /* this code table has been extracted from libwbxml - * (see http://libwbxml.aymerick.com/) by using - * - * grep '\"[^\"]*\", *0x.., 0x.. },' wbxml_tables.c - * | sed -e 's#^.*\"\([^\"]*\)\", *\(0x..\), \(0x..\) },.*$# \$this->setTag\(\3, \"\1\"\); // \2#g' - */ - - $this->setTag(0x05, "Anchor"); // 0x01 - $this->setTag(0x06, "EMI"); // 0x01 - $this->setTag(0x07, "Format"); // 0x01 - $this->setTag(0x08, "FreeID"); // 0x01 - $this->setTag(0x09, "FreeMem"); // 0x01 - $this->setTag(0x0a, "Last"); // 0x01 - $this->setTag(0x0b, "Mark"); // 0x01 - $this->setTag(0x0c, "MaxMsgSize"); // 0x01 - $this->setTag(0x15, "MaxObjSize"); // 0x01 - $this->setTag(0x0d, "Mem"); // 0x01 - $this->setTag(0x0e, "MetInf"); // 0x01 - $this->setTag(0x0f, "Next"); // 0x01 - $this->setTag(0x10, "NextNonce"); // 0x01 - $this->setTag(0x11, "SharedMem"); // 0x01 - $this->setTag(0x12, "Size"); // 0x01 - $this->setTag(0x13, "Type"); // 0x01 - $this->setTag(0x14, "Version"); // 0x01 - $this->setTag(0x15, "MaxObjSize"); // 0x01 - $this->setTag(0x16, "FieldLevel"); // 0x01 - - if ($this->version == 1) { - $this->setCodePage(0, DPI_DTD_SYNCML_1_1, 'syncml:syncml1.1'); - $this->setCodePage(1, DPI_DTD_METINF_1_1, 'syncml:metinf1.1'); - $this->setURI('syncml:metinf1.1'); - //$this->setURI('syncml:metinf'); // for some funny reason, libwbxml produces no :metinf1.1 here - } elseif ($this->version == 2) { - $this->setCodePage(0, DPI_DTD_SYNCML_1_2, 'syncml:syncml1.2'); - $this->setCodePage(1, DPI_DTD_METINF_1_2, 'syncml:metinf1.2'); - $this->setURI('syncml:metinf1.2'); - } else { - $this->setCodePage(0, DPI_DTD_SYNCML_1_0, 'syncml:syncml1.0'); - $this->setCodePage(1, DPI_DTD_METINF_1_0, 'syncml:metinf1.0'); - $this->setURI('syncml:metinf1.0'); - } - } - -} diff --git a/phpgwapi/inc/horde/XML/WBXML/DTDManager.php b/phpgwapi/inc/horde/XML/WBXML/DTDManager.php deleted file mode 100644 index d31cb33fdd..0000000000 --- a/phpgwapi/inc/horde/XML/WBXML/DTDManager.php +++ /dev/null @@ -1,100 +0,0 @@ - - * @package XML_WBXML - */ -class XML_WBXML_DTDManager { - - /** - * @var array - */ - var $_strDTD = array(); - - /** - * @var array - */ - var $_strDTDURI = array(); - - /** - */ - function XML_WBXML_DTDManager() - { - $this->registerDTD(DPI_DTD_SYNCML_1_0, 'syncml:syncml1.0', new XML_WBXML_DTD_SyncML(0)); - $this->registerDTD(DPI_DTD_SYNCML_1_1, 'syncml:syncml1.1', new XML_WBXML_DTD_SyncML(1)); - $this->registerDTD(DPI_DTD_SYNCML_1_2, 'syncml:syncml1.2', new XML_WBXML_DTD_SyncML(2)); - - $this->registerDTD(DPI_DTD_METINF_1_0, 'syncml:metinf1.0', new XML_WBXML_DTD_SyncMLMetInf(0)); - $this->registerDTD(DPI_DTD_METINF_1_1, 'syncml:metinf1.1', new XML_WBXML_DTD_SyncMLMetInf(1)); - $this->registerDTD(DPI_DTD_METINF_1_2, 'syncml:metinf1.2', new XML_WBXML_DTD_SyncMLMetInf(2)); - - $this->registerDTD(DPI_DTD_DEVINF_1_0, 'syncml:devinf1.0', new XML_WBXML_DTD_SyncMLDevInf(0)); - $this->registerDTD(DPI_DTD_DEVINF_1_1, 'syncml:devinf1.1', new XML_WBXML_DTD_SyncMLDevInf(1)); - $this->registerDTD(DPI_DTD_DEVINF_1_2, 'syncml:devinf1.2', new XML_WBXML_DTD_SyncMLDevInf(2)); - } - - /** - */ - function &getInstance($publicIdentifier) - { - $publicIdentifier = strtolower($publicIdentifier); - if (isset($this->_strDTD[$publicIdentifier])) { - $dtd = &$this->_strDTD[$publicIdentifier]; - } else { - $dtd = null; - } - return $dtd; - } - - /** - */ - function &getInstanceURI($uri) - { - $uri = strtolower($uri); - - // some manual hacks: - if ($uri == 'syncml:syncml') { - $uri = 'syncml:syncml1.0'; - } - if ($uri == 'syncml:metinf') { - $uri = 'syncml:metinf1.0'; - } - if ($uri == 'syncml:devinf') { - $uri = 'syncml:devinf1.0'; - } - - if (isset($this->_strDTDURI[$uri])) { - $dtd = &$this->_strDTDURI[$uri]; - } else { - $dtd = null; - } - return $dtd; - } - - /** - */ - function registerDTD($publicIdentifier, $uri, &$dtd) - { - $dtd->setDPI($publicIdentifier); - - $publicIdentifier = strtolower($publicIdentifier); - - $this->_strDTD[$publicIdentifier] = $dtd; - $this->_strDTDURI[strtolower($uri)] = $dtd; - } - -} diff --git a/phpgwapi/inc/horde/XML/WBXML/Decoder.php b/phpgwapi/inc/horde/XML/WBXML/Decoder.php deleted file mode 100644 index a51540eb4f..0000000000 --- a/phpgwapi/inc/horde/XML/WBXML/Decoder.php +++ /dev/null @@ -1,688 +0,0 @@ - - * @package XML_WBXML - */ -class XML_WBXML_Decoder extends XML_WBXML_ContentHandler { - - /** - * Document Public Identifier type - * 1 mb_u_int32 well known type - * 2 string table - * from spec but converted into a string. - * - * Document Public Identifier - * Used with dpiType. - */ - var $_dpi; - - /** - * String table as defined in 5.7 - */ - var $_stringTable = array(); - - /** - * Content handler. - * Currently just outputs raw XML. - */ - var $_ch; - - var $_tagDTD; - - var $_prevAttributeDTD; - - var $_attributeDTD; - - /** - * State variables. - */ - var $_tagStack = array(); - var $_isAttribute; - var $_isData = false; - - var $_error = false; - - /** - * The DTD Manager. - * - * @var XML_WBXML_DTDManager - */ - var $_dtdManager; - - /** - * The string position. - * - * @var integer - */ - var $_strpos; - - /** - * Constructor. - */ - function XML_WBXML_Decoder() - { - $this->_dtdManager = new XML_WBXML_DTDManager(); - } - - /** - * Sets the contentHandler that will receive the output of the - * decoding. - * - * @param XML_WBXML_ContentHandler $ch The contentHandler - */ - function setContentHandler(&$ch) - { - $this->_ch = &$ch; - } - /** - * Return one byte from the input stream. - * - * @param string $input The WBXML input string. - */ - function getByte($input) - { - $value = $input{$this->_strpos++}; - $value = ord($value); - - return $value; - } - - /** - * Takes a WBXML input document and returns decoded XML. - * However the preferred and more effecient method is to - * use decode() rather than decodeToString() and have an - * appropriate contentHandler deal with the decoded data. - * - * @param string $wbxml The WBXML document to decode. - * - * @return string The decoded XML document. - */ - function decodeToString($wbxml) - { - $this->_ch = new XML_WBXML_ContentHandler(); - - $r = $this->decode($wbxml); - if (is_a($r, 'PEAR_Error')) { - return $r; - } - return $this->_ch->getOutput(); - } - - /** - * Takes a WBXML input document and decodes it. - * Decoding result is directly passed to the contentHandler. - * A contenthandler must be set using setContentHandler - * prior to invocation of this method - * - * @param string $wbxml The WBXML document to decode. - * - * @return mixed True on success or PEAR_Error. - */ - function decode($wbxml) - { - $this->_error = false; // reset state - - $this->_strpos = 0; - - if (empty($this->_ch)) { - return $this->raiseError('No Contenthandler defined.'); - } - - // Get Version Number from Section 5.4 - // version = u_int8 - // currently 0, 1 or 2 - $this->_wbxmlVersion = $this->getVersionNumber($wbxml); - #Horde::logMessage("WBXML[" . $this->_strpos . "] version " . $this->_wbxmlVersion, __FILE__, __LINE__, PEAR_LOG_DEBUG); - - // Get Document Public Idetifier from Section 5.5 - // publicid = mb_u_int32 | (zero index) - // zero = u_int8 - // Containing the value zero (0) - // The actual DPI is determined after the String Table is read. - $dpiStruct = $this->getDocumentPublicIdentifier($wbxml); - - // Get Charset from 5.6 - // charset = mb_u_int32 - $this->_charset = $this->getCharset($wbxml); - #Horde::logMessage("WBXML[" . $this->_strpos . "] charset " . $this->_charset, __FILE__, __LINE__, PEAR_LOG_DEBUG); - - // Get String Table from 5.7 - // strb1 = length *byte - $this->retrieveStringTable($wbxml); - - // Get Document Public Idetifier from Section 5.5. - $this->_dpi = $this->getDocumentPublicIdentifierImpl($dpiStruct['dpiType'], - $dpiStruct['dpiNumber']); - #$this->_stringTable); - - // Now the real fun begins. - // From Sections 5.2 and 5.8 - - - // Default content handler. - $this->_dtdManager = new XML_WBXML_DTDManager(); - - // Get the starting DTD. - $this->_tagDTD = $this->_dtdManager->getInstance($this->_dpi); - - if (!$this->_tagDTD) { - return $this->raiseError('No DTD found for ' - . $this->_dpi . '/' - . $dpiStruct['dpiNumber']); - } - - $this->_attributeDTD = $this->_tagDTD; - - while (empty($this->_error) && $this->_strpos < strlen($wbxml)) { - $this->_decode($wbxml); - } - if (!empty($this->_error)) { - return $this->_error; - } - return true; - } - - function getVersionNumber($input) - { - return $this->getByte($input); - } - - function getDocumentPublicIdentifier($input) - { - $i = XML_WBXML::MBUInt32ToInt($input, $this->_strpos); - - if ($i == 0) { - return array('dpiType' => 2, - 'dpiNumber' => $this->getByte($input)); - } else { - return array('dpiType' => 1, - 'dpiNumber' => $i); - } - } - - function getDocumentPublicIdentifierImpl($dpiType, $dpiNumber) - { - if ($dpiType == 1) { - return XML_WBXML::getDPIString($dpiNumber); - } else { - #Horde::logMessage("WBXML string table $dpiNumber:\n" . print_r($this->_stringTable, true), __FILE__, __LINE__, PEAR_LOG_DEBUG); - return $this->getStringTableEntry($dpiNumber); - } - } - - /** - * Returns the character encoding. Only default character - * encodings from J2SE are supported. From - * http://www.iana.org/assignments/character-sets and - * http://java.sun.com/j2se/1.4.2/docs/api/java/nio/charset/Charset.html - */ - function getCharset($input) - { - $cs = XML_WBXML::MBUInt32ToInt($input, $this->_strpos); - return XML_WBXML::getCharsetString($cs); - } - - /** - * Retrieves the string table. - * The string table consists of an mb_u_int32 length - * and then length bytes forming the table. - * References to the string table refer to the - * starting position of the (null terminated) - * string in this table. - */ - function retrieveStringTable($input) - { - $size = XML_WBXML::MBUInt32ToInt($input, $this->_strpos); - $this->_stringTable = $this->_substr($input, $this->_strpos, $size); - $this->_strpos += $size; - // print "stringtable($size):" . $this->_stringTable ."\n"; - } - - function getStringTableEntry($index) - { - if ($index >= strlen($this->_stringTable)) { - $this->_error = - $this->raiseError('Invalid offset ' . $index - . ' value encountered around position ' - . $this->_strpos - . '. Broken wbxml?'); - return ''; - } - - // copy of method termstr but without modification of this->_strpos - - $str = '#'; // must start with nonempty string to allow array access - - $i = 0; - $ch = $this->_stringTable[$index++]; - if (ord($ch) == 0) { - return ''; // don't return '#' - } - - while (ord($ch) != 0) { - $str[$i++] = $ch; - if ($index >= strlen($this->_stringTable)) { - break; - } - $ch = $this->_stringTable[$index++]; - } - // print "string table entry: $str\n"; - return $str; - - } - - function _decode($input) - { - $token = $this->getByte($input); - $str = ''; - - // print "position: " . $this->_strpos . " token: " . $token . " str10: " . substr($input, $this->_strpos, 10) . "\n"; // @todo: remove debug output - - switch ($token) { - case XML_WBXML_GLOBAL_TOKEN_STR_I: - // Section 5.8.4.1 - $str = $this->termstr($input); - $this->_ch->characters($str); - // print "str:$str\n"; // @TODO Remove debug code - break; - - case XML_WBXML_GLOBAL_TOKEN_STR_T: - // Section 5.8.4.1 - $x = XML_WBXML::MBUInt32ToInt($input, $this->_strpos); - $str = $this->getStringTableEntry($x); - $this->_ch->characters($str); - break; - - case XML_WBXML_GLOBAL_TOKEN_EXT_I_0: - case XML_WBXML_GLOBAL_TOKEN_EXT_I_1: - case XML_WBXML_GLOBAL_TOKEN_EXT_I_2: - // Section 5.8.4.2 - $str = $this->termstr($input); - $this->_ch->characters($str); - break; - - case XML_WBXML_GLOBAL_TOKEN_EXT_T_0: - case XML_WBXML_GLOBAL_TOKEN_EXT_T_1: - case XML_WBXML_GLOBAL_TOKEN_EXT_T_2: - // Section 5.8.4.2 - $str = $this->getStringTableEnty(XML_WBXML::MBUInt32ToInt($input, $this->_strpos)); - $this->_ch->characters($str); - break; - - case XML_WBXML_GLOBAL_TOKEN_EXT_0: - case XML_WBXML_GLOBAL_TOKEN_EXT_1: - case XML_WBXML_GLOBAL_TOKEN_EXT_2: - // Section 5.8.4.2 - $extension = $this->getByte($input); - $this->_ch->characters($extension); - break; - - case XML_WBXML_GLOBAL_TOKEN_ENTITY: - // Section 5.8.4.3 - // UCS-4 chracter encoding? - $entity = $this->entity(XML_WBXML::MBUInt32ToInt($input, $this->_strpos)); - - $this->_ch->characters('&#' . $entity . ';'); - break; - - case XML_WBXML_GLOBAL_TOKEN_PI: - // Section 5.8.4.4 - // throw new IOException - // die("WBXML global token processing instruction(PI, " + token + ") is unsupported!\n"); - break; - - case XML_WBXML_GLOBAL_TOKEN_LITERAL: - // Section 5.8.4.5 - $str = $this->getStringTableEntry(XML_WBXML::MBUInt32ToInt($input, $this->_strpos)); - $this->parseTag($input, $str, false, false); - break; - - case XML_WBXML_GLOBAL_TOKEN_LITERAL_A: - // Section 5.8.4.5 - $str = $this->getStringTableEntry(XML_WBXML::MBUInt32ToInt($input, $this->_strpos)); - $this->parseTag($input, $str, true, false); - break; - - case XML_WBXML_GLOBAL_TOKEN_LITERAL_AC: - // Section 5.8.4.5 - $str = $this->getStringTableEntry(XML_WBXML::MBUInt32ToInt($input, $this->_strpos)); - $this->parseTag($input, $string, true, true); - break; - - case XML_WBXML_GLOBAL_TOKEN_LITERAL_C: - // Section 5.8.4.5 - $str = $this->getStringTableEntry(XML_WBXML::MBUInt32ToInt($input, $this->_strpos)); - $this->parseTag($input, $str, false, true); - break; - - case XML_WBXML_GLOBAL_TOKEN_OPAQUE: - // Section 5.8.4.6 - $size = XML_WBXML::MBUInt32ToInt($input, $this->_strpos); - if ($size > 0) { - #Horde::logMessage("WBXML opaque document size=$size, next=" . ord($input{$this->_strpos}), __FILE__, __LINE__, PEAR_LOG_DEBUG); - $b = $this->_substr($input, $this->_strpos, $size); - // print "opaque of size $size: ($b)\n"; // @todo remove debug - $this->_strpos += $size; - // opaque data inside a element may or may not be - // a nested wbxml document (for example devinf data). - // We find out by checking the first byte of the data: if it's - // 1, 2 or 3 we expect it to be the version number of a wbxml - // document and thus start a new wbxml decoder instance on it. - - if ($this->_isData && ord($b) < 10) { - #Horde::logMessage("WBXML opaque document size=$size, \$b[0]=" . ord($b), __FILE__, __LINE__, PEAR_LOG_DEBUG); - $decoder = new XML_WBXML_Decoder(true); - $decoder->setContentHandler($this->_ch); - $s = $decoder->decode($b); - // /* // @todo: FIXME currently we can't decode Nokia - // DevInf data. So ignore error for the time beeing. - if (is_a($s, 'PEAR_Error')) { - $this->_error = $s; - return; - } - // */ - // $this->_ch->characters($s); - } else { - /* normal opaque behaviour: just copy the raw data: */ - // print "opaque handled as string=$b\n"; // @todo remove debug - $this->_ch->characters($b); - } - } - // old approach to deal with opaque data inside ContentHandler: - // FIXME Opaque is used by SYNCML. Opaque data that depends on the context - // if (contentHandler instanceof OpaqueContentHandler) { - // ((OpaqueContentHandler)contentHandler).opaque(b); - // } else { - // String str = new String(b, 0, size, charset); - // char[] chars = str.toCharArray(); - - // contentHandler.characters(chars, 0, chars.length); - // } - - break; - - case XML_WBXML_GLOBAL_TOKEN_END: - // Section 5.8.4.7.1 - $str = $this->endTag(); - break; - - case XML_WBXML_GLOBAL_TOKEN_SWITCH_PAGE: - // Section 5.8.4.7.2 - $codePage = $this->getByte($input); - // print "switch to codepage $codePage\n"; // @todo: remove debug code - $this->switchElementCodePage($codePage); - break; - - default: - // Section 5.8.2 - // Section 5.8.3 - $hasAttributes = (($token & 0x80) != 0); - $hasContent = (($token & 0x40) != 0); - $realToken = $token & 0x3F; - $str = $this->getTag($realToken); - - // print "element:$str\n"; // @TODO Remove debug code - $this->parseTag($input, $str, $hasAttributes, $hasContent); - - if ($realToken == 0x0f) { - // store if we're inside a Data tag. This may contain - // an additional enclosed wbxml document on which we have - // to run a seperate encoder - $this->_isData = true; - } else { - $this->_isData = false; - } - break; - } - } - - function parseTag($input, $tag, $hasAttributes, $hasContent) - { - $attrs = array(); - if ($hasAttributes) { - $attrs = $this->getAttributes($input); - } - - $this->_ch->startElement($this->getCurrentURI(), $tag, $attrs); - - if ($hasContent) { - // FIXME I forgot what does this does. Not sure if this is - // right? - $this->_tagStack[] = $tag; - } else { - $this->_ch->endElement($this->getCurrentURI(), $tag); - } - } - - function endTag() - { - if (count($this->_tagStack)) { - $tag = array_pop($this->_tagStack); - } else { - $tag = 'Unknown'; - } - - $this->_ch->endElement($this->getCurrentURI(), $tag); - - return $tag; - } - - function getAttributes($input) - { - $this->startGetAttributes(); - $hasMoreAttributes = true; - - $attrs = array(); - $attr = null; - $value = null; - $token = null; - - while ($hasMoreAttributes) { - $token = $this->getByte($input); - - switch ($token) { - // Attribute specified. - case XML_WBXML_GLOBAL_TOKEN_LITERAL: - // Section 5.8.4.5 - if (isset($attr)) { - $attrs[] = array('attribute' => $attr, - 'value' => $value); - } - - $attr = $this->getStringTableEntry(XML_WBXML::MBUInt32ToInt($input, $this->_strpos)); - break; - - // Value specified. - case XML_WBXML_GLOBAL_TOKEN_EXT_I_0: - case XML_WBXML_GLOBAL_TOKEN_EXT_I_1: - case XML_WBXML_GLOBAL_TOKEN_EXT_I_2: - // Section 5.8.4.2 - $value .= $this->termstr($input); - break; - - case XML_WBXML_GLOBAL_TOKEN_EXT_T_0: - case XML_WBXML_GLOBAL_TOKEN_EXT_T_1: - case XML_WBXML_GLOBAL_TOKEN_EXT_T_2: - // Section 5.8.4.2 - $value .= $this->getStringTableEntry(XML_WBXML::MBUInt32ToInt($input, $this->_strpos)); - break; - - case XML_WBXML_GLOBAL_TOKEN_EXT_0: - case XML_WBXML_GLOBAL_TOKEN_EXT_1: - case XML_WBXML_GLOBAL_TOKEN_EXT_2: - // Section 5.8.4.2 - $value .= $input[$this->_strpos++]; - break; - - case XML_WBXML_GLOBAL_TOKEN_ENTITY: - // Section 5.8.4.3 - $value .= $this->entity(XML_WBXML::MBUInt32ToInt($input, $this->_strpos)); - break; - - case XML_WBXML_GLOBAL_TOKEN_STR_I: - // Section 5.8.4.1 - $value .= $this->termstr($input); - break; - - case XML_WBXML_GLOBAL_TOKEN_STR_T: - // Section 5.8.4.1 - $value .= $this->getStringTableEntry(XML_WBXML::MBUInt32ToInt($input, $this->_strpos)); - break; - - case XML_WBXML_GLOBAL_TOKEN_OPAQUE: - // Section 5.8.4.6 - $size = XML_WBXML::MBUInt32ToInt($input, $this->_strpos); - $b = $this->_substr($input, $this->_strpos, $this->_strpos + $size); - $this->_strpos += $size; - - $value .= $b; - break; - - case XML_WBXML_GLOBAL_TOKEN_END: - // Section 5.8.4.7.1 - $hasMoreAttributes = false; - if (isset($attr)) { - $attrs[] = array('attribute' => $attr, - 'value' => $value); - } - break; - - case XML_WBXML_GLOBAL_TOKEN_SWITCH_PAGE: - // Section 5.8.4.7.2 - $codePage = $this->getByte($input); - if (!$this->_prevAttributeDTD) { - $this->_prevAttributeDTD = $this->_attributeDTD; - } - - $this->switchAttributeCodePage($codePage); - break; - - default: - if ($token > 128) { - if (isset($attr)) { - $attrs[] = array('attribute' => $attr, - 'value' => $value); - } - $attr = $this->_attributeDTD->toAttribute($token); - } else { - // Value. - $value .= $this->_attributeDTD->toAttribute($token); - } - break; - } - } - - if (!$this->_prevAttributeDTD) { - $this->_attributeDTD = $this->_prevAttributeDTD; - $this->_prevAttributeDTD = false; - } - - $this->stopGetAttributes(); - } - - function startGetAttributes() - { - $this->_isAttribute = true; - } - - function stopGetAttributes() - { - $this->_isAttribute = false; - } - - function getCurrentURI() - { - if ($this->_isAttribute) { - return $this->_tagDTD->getURI(); - } else { - return $this->_attributeDTD->getURI(); - } - } - - function writeString($str) - { - $this->_ch->characters($str); - } - - function getTag($tag) - { - // Should know which state it is in. - return $this->_tagDTD->toTagStr($tag); - } - - function getAttribute($attribute) - { - // Should know which state it is in. - $this->_attributeDTD->toAttributeInt($attribute); - } - - function switchElementCodePage($codePage) - { - $this->_tagDTD = &$this->_dtdManager->getInstance($this->_tagDTD->toCodePageStr($codePage)); - $this->switchAttributeCodePage($codePage); - } - - function switchAttributeCodePage($codePage) - { - $this->_attributeDTD = &$this->_dtdManager->getInstance($this->_attributeDTD->toCodePageStr($codePage)); - } - - /** - * Return the hex version of the base 10 $entity. - */ - function entity($entity) - { - return dechex($entity); - } - - /** - * Reads a null terminated string. - */ - function termstr($input) - { - $str = '#'; // must start with nonempty string to allow array access - $i = 0; - $ch = $input[$this->_strpos++]; - if (ord($ch) == 0) { - return ''; // don't return '#' - } - while (ord($ch) != 0) { - $str[$i++] = $ch; - $ch = $input[$this->_strpos++]; - } - - return $str; - } - - /** - * imitate substr() - * This circumvents a bug in the mbstring overloading in some distributions, - * where the mbstring.func_overload=0 INI-setting does not work, if mod_php - * has another value for that setting in another directory-context - */ - function _substr($input,$start,$size) - { - $ret = ""; - if (!$input) return $ret; - for ($i = $start; $i < $start+$size; $i++) { - $ret .= $input[$i]; - } - return $ret; - } -} - diff --git a/phpgwapi/inc/horde/XML/WBXML/Encoder.php b/phpgwapi/inc/horde/XML/WBXML/Encoder.php deleted file mode 100644 index 39860df82f..0000000000 --- a/phpgwapi/inc/horde/XML/WBXML/Encoder.php +++ /dev/null @@ -1,425 +0,0 @@ - - * @package XML_WBXML - */ -class XML_WBXML_Encoder extends XML_WBXML_ContentHandler { - - var $_strings = array(); - - var $_stringTable; - - var $_hasWrittenHeader = false; - - var $_dtd; - - var $_output = ''; - - var $_uris = array(); - - var $_uriNums = array(); - - var $_currentURI; - - var $_subParser = null; - var $_subParserStack = 0; - - /** - * The XML parser. - * - * @var resource - */ - var $_parser; - - /** - * The DTD Manager. - * - * @var XML_WBXML_DTDManager - */ - var $_dtdManager; - - /** - * Constructor. - */ - function XML_WBXML_Encoder() - { - $this->_dtdManager = new XML_WBXML_DTDManager(); - $this->_stringTable = new XML_WBXML_HashTable(); - } - - /** - * Take the input $xml and turn it into WBXML. This is _not_ the - * intended way of using this class. It is derived from - * Contenthandler and one should use it as a ContentHandler and - * produce the XML-structure with startElement(), endElement(), - * and characters(). - */ - function encode($xml) - { - // Create the XML parser and set method references. - $this->_parser = xml_parser_create_ns($this->_charset); - xml_set_object($this->_parser, $this); - xml_parser_set_option($this->_parser, XML_OPTION_CASE_FOLDING, false); - xml_set_element_handler($this->_parser, '_startElement', '_endElement'); - xml_set_character_data_handler($this->_parser, '_characters'); - xml_set_processing_instruction_handler($this->_parser, ''); - xml_set_external_entity_ref_handler($this->_parser, ''); - - if (!xml_parse($this->_parser, $xml)) { - return $this->raiseError(sprintf('XML error: %s at line %d', - xml_error_string(xml_get_error_code($this->_parser)), - xml_get_current_line_number($this->_parser))); - } - - xml_parser_free($this->_parser); - - return $this->_output; - } - - /** - * This will write the correct headers. - */ - function writeHeader($uri) - { - $this->_dtd = &$this->_dtdManager->getInstanceURI($uri); - if (!$this->_dtd) { - // TODO: proper error handling - die('Unable to find dtd for ' . $uri); - } - $dpiString = $this->_dtd->getDPI(); - - // Set Version Number from Section 5.4 - // version = u_int8 - // currently 1, 2 or 3 - $this->writeVersionNumber($this->_wbxmlVersion); - - // Set Document Public Idetifier from Section 5.5 - // publicid = mb_u_int32 | ( zero index ) - // zero = u_int8 - // containing the value zero (0) - // The actual DPI is determined after the String Table is read. - $this->writeDocumentPublicIdentifier($dpiString, $this->_strings); - - // Set Charset from 5.6 - // charset = mb_u_int32 - $this->writeCharset($this->_charset); - - // Set String Table from 5.7 - // strb1 = length *byte - $this->writeStringTable($this->_strings, $this->_charset, $this->_stringTable); - - $this->_currentURI = $uri; - - $this->_hasWrittenHeader = true; - } - - function writeVersionNumber($version) - { - $this->_output .= chr($version); - } - - function writeDocumentPublicIdentifier($dpiString, &$strings) - { - $i = 0; - - // The OMA test suite doesn't like DPI as integer code. - // So don't try lookup and always send full DPI string. - // $i = XML_WBXML::getDPIInt($dpiString); - - if ($i == 0) { - $strings[0] = $dpiString; - $this->_output .= chr(0); - $this->_output .= chr(0); - } else { - XML_WBXML::intToMBUInt32($this->_output, $i); - } - } - - function writeCharset($charset) - { - $cs = XML_WBXML::getCharsetInt($charset); - - if ($cs == 0) { - return $this->raiseError('Unsupported Charset: ' . $charset); - } else { - XML_WBXML::intToMBUInt32($this->_output, $cs); - } - } - - function writeStringTable($strings, $charset, $stringTable) - { - $stringBytes = array(); - $count = 0; - foreach ($strings as $str) { - $bytes = $this->_getBytes($str, $charset); - $stringBytes = array_merge($stringBytes, $bytes); - $nullLength = $this->_addNullByte($bytes); - $this->_stringTable->set($str, $count); - $count += count($bytes) + $nullLength; - } - - XML_WBXML::intToMBUInt32($this->_output, count($stringBytes)); - $this->_output .= implode('', $stringBytes); - } - - function writeString($str, $cs) - { - $bytes = $this->_getBytes($str, $cs); - $this->_output .= implode('', $bytes); - $this->writeNull($cs); - } - - function writeNull($charset) - { - $this->_output .= chr(0); - return 1; - } - - function _addNullByte(&$bytes) - { - $bytes[] = chr(0); - return 1; - } - - function _getBytes($string, $cs) - { - $string = String::convertCharset($string, $cs, 'utf-8'); - $nbytes = strlen($string); - - $bytes = array(); - for ($i = 0; $i < $nbytes; $i++) { - $bytes[] = $string{$i}; - } - - return $bytes; - } - - function _splitURI($tag) - { - $parts = explode(':', $tag); - $name = array_pop($parts); - $uri = implode(':', $parts); - return array($uri, $name); - } - - function startElement($uri, $name, $attributes = array()) - { - #Horde::logMessage("WBXML Encoder $uri, " . ($this->_hasWrittenHeader ? 'true' : 'false'), __FILE__, __LINE__, PEAR_LOG_DEBUG); - - if ($this->_subParser == null) { - if (!$this->_hasWrittenHeader) { - $this->writeHeader($uri); - } - if ($this->_currentURI != $uri) { - $this->changecodepage($uri); - } - if ($this->_subParser == null) { - $this->writeTag($name, $attributes, true, $this->_charset); - } else { - $this->_subParser->startElement($uri, $name, $attributes); - } - } else { - $this->_subParserStack++; - $this->_subParser->startElement($uri, $name, $attributes); - } - } - - function _startElement($parser, $tag, $attributes) - { - list($uri, $name) = $this->_splitURI($tag); - - $this->startElement($uri, $name, $attributes); - } - - function opaque($o) - { - if ($this->_subParser == null) { - $this->_output .= chr(XML_WBXML_GLOBAL_TOKEN_OPAQUE); - XML_WBXML::intToMBUInt32($this->_output, strlen($o)); - $this->_output .= $o; - } - } - - function characters($chars) - { - $chars = trim($chars); - - if (strlen($chars)) { - /* We definitely don't want any whitespace. */ - if ($this->_subParser == null) { - $i = $this->_stringTable->get($chars); - if ($i != null) { - $this->_output .= chr(XML_WBXML_GLOBAL_TOKEN_STR_T); - XML_WBXML::intToMBUInt32($this->_output, $i); - } else { - $this->_output .= chr(XML_WBXML_GLOBAL_TOKEN_STR_I); - $this->writeString($chars, $this->_charset); - } - } else { - $this->_subParser->characters($chars); - } - } - } - - function _characters($parser, $chars) - { - $this->characters($chars); - } - - function writeTag($name, $attrs, $hasContent, $cs) - { - if ($attrs != null && !count($attrs)) { - $attrs = null; - } - - $t = $this->_dtd->toTagInt($name); - if ($t == -1) { - $i = $this->_stringTable->get($name); - if ($i == null) { - return $this->raiseError($name . ' is not found in String Table or DTD'); - } else { - if ($attrs == null && !$hasContent) { - $this->_output .= chr(XML_WBXML_GLOBAL_TOKEN_LITERAL); - } elseif ($attrs == null && $hasContent) { - $this->_output .= chr(XML_WBXML_GLOBAL_TOKEN_LITERAL_A); - } elseif ($attrs != null && $hasContent) { - $this->_output .= chr(XML_WBXML_GLOBAL_TOKEN_LITERAL_C); - } elseif ($attrs != null && !$hasContent) { - $this->_output .= chr(XML_WBXML_GLOBAL_TOKEN_LITERAL_AC); - } - - XML_WBXML::intToMBUInt32($this->_output, $i); - } - } else { - if ($attrs == null && !$hasContent) { - $this->_output .= chr($t); - } elseif ($attrs == null && $hasContent) { - $this->_output .= chr($t | 64); - } elseif ($attrs != null && $hasContent) { - $this->_output .= chr($t | 128); - } elseif ($attrs != null && !$hasContent) { - $this->_output .= chr($t | 192); - } - } - - if ($attrs != null && is_array($attrs) && count($attrs) > 0) { - $this->writeAttributes($attrs, $cs); - } - } - - function writeAttributes($attrs, $cs) - { - foreach ($attrs as $name => $value) { - $this->writeAttribute($name, $value, $cs); - } - - $this->_output .= chr(XML_WBXML_GLOBAL_TOKEN_END); - } - - function writeAttribute($name, $value, $cs) - { - $a = $this->_dtd->toAttribute($name); - if ($a == -1) { - $i = $this->_stringTable->get($name); - if ($i == null) { - return $this->raiseError($name . ' is not found in String Table or DTD'); - } else { - $this->_output .= chr(XML_WBXML_GLOBAL_TOKEN_LITERAL); - XML_WBXML::intToMBUInt32($this->_output, $i); - } - } else { - $this->_output .= $a; - } - - $i = $this->_stringTable->get($name); - if ($i != null) { - $this->_output .= chr(XML_WBXML_GLOBAL_TOKEN_STR_T); - XML_WBXML::intToMBUInt32($this->_output, $i); - } else { - $this->_output .= chr(XML_WBXML_GLOBAL_TOKEN_STR_I); - $this->writeString($value, $cs); - } - } - - function endElement($uri, $name) - { - if ($this->_subParser == null) { - $this->_output .= chr(XML_WBXML_GLOBAL_TOKEN_END); - } else { - $this->_subParser->endElement($uri, $name); - $this->_subParserStack--; - - if ($this->_subParserStack == 0) { - $this->_output .= chr(XML_WBXML_GLOBAL_TOKEN_OPAQUE); - - XML_WBXML::intToMBUInt32($this->_output, - strlen($this->_subParser->getOutput())); - $this->_output .= $this->_subParser->getOutput(); - - $this->_subParser = null; - } - } - } - - function _endElement($parser, $tag) - { - list($uri, $name) = $this->_splitURI($tag); - $this->endElement($uri, $name); - } - - function changecodepage($uri) - { - if ($this->_dtd->getVersion() == 2 && !preg_match('/1\.2$/', $uri)) { - $uri .= '1.2'; - } - if ($this->_dtd->getVersion() == 1 && !preg_match('/1\.1$/', $uri)) { - $uri .= '1.1'; - } - if ($this->_dtd->getVersion() == 0 && !preg_match('/1\.0$/', $uri)) { - $uri .= '1.0'; - } - - $cp = $this->_dtd->toCodePageURI($uri); - if (strlen($cp)) { - $this->_dtd = &$this->_dtdManager->getInstanceURI($uri); - - $this->_output .= chr(XML_WBXML_GLOBAL_TOKEN_SWITCH_PAGE); - $this->_output .= chr($cp); - $this->_currentURI = $uri; - - } else { - $this->_subParser = new XML_WBXML_Encoder(true); - $this->_subParserStack = 1; - } - } - - /** - * Getter for property output. - */ - function getOutput() - { - return $this->_output; - } - - function getOutputSize() - { - return strlen($this->_output); - } - -} diff --git a/phpgwapi/inc/horde/config/conf.php b/phpgwapi/inc/horde/config/conf.php deleted file mode 100644 index 07bb3a80d9..0000000000 --- a/phpgwapi/inc/horde/config/conf.php +++ /dev/null @@ -1,44 +0,0 @@ -applications['horde'] = array( - 'fileroot' => dirname(__FILE__) . '/..', - 'webroot' => $webroot, - 'initial_page' => 'login.php', - 'icon' => $webroot . '/graphics/horde.png', - 'name' => _("Horde"), - 'status' => 'active', - 'templates' => dirname(__FILE__) . '/../templates', - 'provides' => 'horde' -); - -#$this->applications['mnemo'] = array( -# 'fileroot' => dirname(__FILE__) . '/../mnemo', -# 'webroot' => $this->applications['horde']['webroot'] . '/mnemo', -# 'icon' => $this->applications['horde']['webroot'] . '/mnemo/graphics/mnemo.gif', -# 'name' => _("Notes"), -# 'status' => 'active', -# 'provides' => 'notes', -# 'menu_parent' => 'organizing' -#); - -$this->applications['egwnotessync'] = array( - 'fileroot' => EGW_SERVER_ROOT.'/syncml/notes', - 'webroot' => $this->applications['horde']['webroot'] . '/mnemo', - 'icon' => $this->applications['horde']['webroot'] . '/mnemo/graphics/mnemo.gif', - 'name' => _("Notes"), - 'status' => 'active', - 'provides' => array('notes', 'sifnotes', 'snote'), - 'menu_parent' => 'organizing' -); - -$this->applications['egwcontactssync'] = array( - 'fileroot' => EGW_SERVER_ROOT.'/syncml/contacts', - 'webroot' => $this->applications['horde']['webroot'] . '/mnemo', - 'icon' => $this->applications['horde']['webroot'] . '/mnemo/graphics/mnemo.gif', - 'name' => _("Contacts"), - 'status' => 'active', - 'provides' => array('contacts', 'sifcontacts', 'scard', 'card'), - 'menu_parent' => 'organizing' -); - -#$this->applications['egwsifcontactssync'] = array( -# 'fileroot' => EGW_SERVER_ROOT.'/syncml/sifcontacts', -# 'webroot' => $this->applications['horde']['webroot'] . '/mnemo', -# 'icon' => $this->applications['horde']['webroot'] . '/mnemo/graphics/mnemo.gif', -# 'name' => _("SIF Contacts"), -# 'status' => 'active', -# 'provides' => 'sifcontacts', -# 'menu_parent' => 'organizing' -#); - -$this->applications['egwcalendarsync'] = array( - 'fileroot' => EGW_SERVER_ROOT.'/syncml/calendar', - 'webroot' => $this->applications['horde']['webroot'] . '/mnemo', - 'icon' => $this->applications['horde']['webroot'] . '/mnemo/graphics/mnemo.gif', - 'name' => _("Calendar"), - 'status' => 'active', - 'provides' => array('calendar', 'sifcalendar', 'scal', 'events'), - 'menu_parent' => 'organizing' -); - -#$this->applications['egwsifcalendarsync'] = array( -# 'fileroot' => EGW_SERVER_ROOT.'/syncml/sifcalendar', -# 'webroot' => $this->applications['horde']['webroot'] . '/mnemo', -# 'icon' => $this->applications['horde']['webroot'] . '/mnemo/graphics/mnemo.gif', -# 'name' => _("Calendar"), -# 'status' => 'active', -# 'provides' => 'sifcalendar', -# 'menu_parent' => 'organizing' -#); - -$this->applications['egwtaskssync'] = array( - 'fileroot' => EGW_SERVER_ROOT.'/syncml/tasks', - 'webroot' => $this->applications['horde']['webroot'] . '/mnemo', - 'icon' => $this->applications['horde']['webroot'] . '/mnemo/graphics/mnemo.gif', - 'name' => _("Tasks"), - 'status' => 'active', - 'provides' => array('tasks', 'siftasks', 'stask', 'jobs'), - 'menu_parent' => 'organizing' -); - -#$this->applications['egwsiftaskssync'] = array( -# 'fileroot' => EGW_SERVER_ROOT.'/syncml/siftasks', -# 'webroot' => $this->applications['horde']['webroot'] . '/mnemo', -# 'icon' => $this->applications['horde']['webroot'] . '/mnemo/graphics/mnemo.gif', -# 'name' => _("SIFTasks"), -# 'status' => 'active', -# 'provides' => array('siftasks', 'stask'), -# 'menu_parent' => 'organizing' -#); - -$this->applications['egwcaltaskssync'] = array( - 'fileroot' => EGW_SERVER_ROOT.'/syncml/caltasks', - 'webroot' => $this->applications['horde']['webroot'] . '/mnemo', - 'icon' => $this->applications['horde']['webroot'] . '/mnemo/graphics/mnemo.gif', - 'name' => _("Calendar and Tasks"), - 'status' => 'active', - 'provides' => 'caltasks', - 'menu_parent' => 'organizing' -); - -$this->applications['egwconfigurationsync'] = array( - 'fileroot' => EGW_SERVER_ROOT.'/syncml/configuration', - 'webroot' => $this->applications['horde']['webroot'] . '/mnemo', - 'icon' => $this->applications['horde']['webroot'] . '/mnemo/graphics/mnemo.gif', - 'name' => _("Funambol Configurations"), - 'status' => 'active', - 'provides' => array('configuration'), - 'menu_parent' => 'organizing' -); - diff --git a/phpgwapi/inc/horde/lib/base.php b/phpgwapi/inc/horde/lib/base.php deleted file mode 100644 index 3137eb1efd..0000000000 --- a/phpgwapi/inc/horde/lib/base.php +++ /dev/null @@ -1,54 +0,0 @@ - - * - * See the enclosed file COPYING for license information (LGPL). If you - * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html. - */ - -// Check for a prior definition of HORDE_BASE (perhaps by an -// auto_prepend_file definition for site customization). -#if (!defined('HORDE_BASE')) { -# @define('HORDE_BASE', dirname(__FILE__) . '/..'); -#} - -// Load the Horde Framework core, and set up inclusion paths. -#require_once HORDE_BASE . '/lib/core.php'; - -// Registry. -if (Util::nonInputVar('session_control') == 'none') { - $registry = &Registry::singleton(HORDE_SESSION_NONE); -} else { - $registry = &Registry::singleton(); -} -#if (is_a(($pushed = $registry->pushApp('horde', !defined('AUTH_HANDLER'))), 'PEAR_Error')) { -# if ($pushed->getCode() == 'permission_denied') { -# Horde::authenticationFailureRedirect(); -# } -# Horde::fatal($pushed, __FILE__, __LINE__, false); -#} -$conf = &$GLOBALS['conf']; -#@define('HORDE_TEMPLATES', $registry->get('templates')); - -// Notification System. -#$notification = &Notification::singleton(); -#$notification->attach('status'); - -/* Set up the menu. */ -#require_once 'Horde/Menu.php'; -#$menu = new Menu(); - -// Compress output -#Horde::compressOutput(); diff --git a/phpgwapi/inc/horde/lib/core.php b/phpgwapi/inc/horde/lib/core.php deleted file mode 100644 index 13454b6b28..0000000000 --- a/phpgwapi/inc/horde/lib/core.php +++ /dev/null @@ -1,56 +0,0 @@ - - * - * See the enclosed file COPYING for license information (LGPL). If you - * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html. - */ - -/* Turn PHP stuff off that can really screw things up. */ -ini_set('magic_quotes_sybase', 0); -ini_set('magic_quotes_runtime', 0); - -/* If the Horde Framework packages are not installed in PHP's global - * include_path, you must add an ini_set() call here to add their location to - * the include_path. */ -// ini_set('include_path', dirname(__FILE__) . PATH_SEPARATOR . ini_get('include_path')); -//set_include_path(dirname(__FILE__). '/../../horde/' . PATH_SEPARATOR . dirname(__FILE__). '/../../../../egw-pear/' . PATH_SEPARATOR . get_include_path()); - -@define('EGW_BASE', realpath(dirname(dirname(__FILE__) . '/../../../../rpc.php'))); -// Check for a prior definition of HORDE_BASE (perhaps by an -// auto_prepend_file definition for site customization). -if (!defined('HORDE_BASE')) { - @define('HORDE_BASE', EGW_BASE . '/phpgwapi/inc/horde/'); -} - -$save_include_path = set_include_path(HORDE_BASE . PATH_SEPARATOR . get_include_path()); -/* PEAR base class. */ -include_once 'PEAR.php'; - -/* Horde core classes. */ -include_once 'Horde.php'; -include_once 'Horde/Registry.php'; -#include_once 'Horde/DataTree.php'; -include_once 'Horde/String.php'; -include_once 'Horde/Date.php'; -include_once 'Horde/NLS.php'; -include_once 'Horde/iCalendar.php'; -//include_once 'Horde/Notification.php'; -//include_once 'Horde/Auth.php'; -//include_once 'Horde/Browser.php'; -//include_once 'Horde/Perms.php'; - -/* Browser detection object. * -if (class_exists('Browser')) { - $browser = &Browser::singleton(); -} -*/ -// restore EGroupware include path to NOT conflict with new Horde code installed in include-path -set_include_path($save_include_path); \ No newline at end of file