Revision: 18640 http://svn.sv.gnu.org/viewvc/?view=rev&root=phpgroupware&revision=18640 Author: johang Date: 2008-07-05 21:09:56 +0000 (Sat, 05 Jul 2008)
Log Message: ----------- * Refactored syncml_message. * Hopefully solved the CDATA issue; some data items should be wrapped with CDATA tags. * Rewrote some stuff in syncml_response. * Something about WBXML and devinf is broken. * Better logging. Modified Paths: -------------- trunk/syncml/inc/class.syncml_auth_basic.inc.php trunk/syncml/inc/class.syncml_auth_md5.inc.php trunk/syncml/inc/class.syncml_command_get.inc.php trunk/syncml/inc/class.syncml_command_replace.inc.php trunk/syncml/inc/class.syncml_command_synchdr.inc.php trunk/syncml/inc/class.syncml_database.inc.php trunk/syncml/inc/class.syncml_database_devinf.inc.php trunk/syncml/inc/class.syncml_logger.inc.php trunk/syncml/inc/class.syncml_message.inc.php trunk/syncml/inc/class.syncml_response.inc.php trunk/syncml/inc/functions.inc.php trunk/syncml/syncml.php Modified: trunk/syncml/inc/class.syncml_auth_basic.inc.php =================================================================== --- trunk/syncml/inc/class.syncml_auth_basic.inc.php 2008-07-04 16:41:50 UTC (rev 18639) +++ trunk/syncml/inc/class.syncml_auth_basic.inc.php 2008-07-05 21:09:56 UTC (rev 18640) @@ -27,8 +27,12 @@ // $data is in the form username:password. // neither username nor password should contain colon. @list($username, $passwd) = explode(':', $data, 2); + + syncml_logger::get_instance()->log_data("Processing credentials (basic)", + array($username, $passwd)); - return $GLOBALS['phpgw']->session->create($username, $passwd); + return $GLOBALS['phpgw']->session->create( + $username, md5($passwd), 'md5'); } } ?> Modified: trunk/syncml/inc/class.syncml_auth_md5.inc.php =================================================================== --- trunk/syncml/inc/class.syncml_auth_md5.inc.php 2008-07-04 16:41:50 UTC (rev 18639) +++ trunk/syncml/inc/class.syncml_auth_md5.inc.php 2008-07-05 21:09:56 UTC (rev 18640) @@ -58,6 +58,9 @@ $passwd = $GLOBALS['phpgw']->db->f('account_pwd'); $username = $GLOBALS['phpgw']->db->f('account_lid'); + syncml_logger::get_instance()->log_data("Processing credentials (md5)", + array($username, $passwd)); + return $GLOBALS['phpgw']->session->create($username, $passwd, true); } } Modified: trunk/syncml/inc/class.syncml_command_get.inc.php =================================================================== --- trunk/syncml/inc/class.syncml_command_get.inc.php 2008-07-04 16:41:50 UTC (rev 18639) +++ trunk/syncml/inc/class.syncml_command_get.inc.php 2008-07-05 21:09:56 UTC (rev 18640) @@ -42,7 +42,7 @@ if(!$database) { // No database or source is given. Try getting one by type. - + switch($this->meta['type']) { case 'application/vnd.syncml-devinf+xml': Modified: trunk/syncml/inc/class.syncml_command_replace.inc.php =================================================================== --- trunk/syncml/inc/class.syncml_command_replace.inc.php 2008-07-04 16:41:50 UTC (rev 18639) +++ trunk/syncml/inc/class.syncml_command_replace.inc.php 2008-07-05 21:09:56 UTC (rev 18640) @@ -96,6 +96,8 @@ } else { + // @todo send some kind of error code instead of OK + $response->add_status( $this->cmdid, $session->msgid, 'Replace', NULL, NULL, Modified: trunk/syncml/inc/class.syncml_command_synchdr.inc.php =================================================================== --- trunk/syncml/inc/class.syncml_command_synchdr.inc.php 2008-07-04 16:41:50 UTC (rev 18639) +++ trunk/syncml/inc/class.syncml_command_synchdr.inc.php 2008-07-05 21:09:56 UTC (rev 18640) @@ -142,15 +142,11 @@ if(is_string($tmp)) { - syncml_logger::get_instance()->log( - "credentials was OK"); $sosession->set_session_mapping($id, $tmp); $this->handle_success($response, $session); } else { - syncml_logger::get_instance()->log( - "bad credentials"); $this->handle_failure($tmp, $response, $session); } } @@ -161,6 +157,8 @@ function handle_success(&$response, &$session) { + syncml_logger::get_instance()->log("auth success"); + $session->account_id = $GLOBALS['phpgw']->session->account_id; $session->session_data = $GLOBALS['phpgw']->session->appsession( @@ -182,6 +180,8 @@ */ function handle_failure($code, &$response, &$session) { + syncml_logger::get_instance()->log("auth failure"); + switch($code) { case SYNCML_STATUS_PROTOCOLVERSIONNOTSUPPORTED: Modified: trunk/syncml/inc/class.syncml_database.inc.php =================================================================== --- trunk/syncml/inc/class.syncml_database.inc.php 2008-07-04 16:41:50 UTC (rev 18639) +++ trunk/syncml/inc/class.syncml_database.inc.php 2008-07-05 21:09:56 UTC (rev 18640) @@ -91,9 +91,9 @@ d.source_id = s.source_id', $channel_id), __LINE__, __FILE__); - + $GLOBALS['phpgw']->db->next_record(); - + return array( $GLOBALS['phpgw']->db->f('modulename'), $GLOBALS['phpgw']->db->f('mimetype'), @@ -129,31 +129,30 @@ */ function merge_changes($except_list = array()) { - syncml_logger::get_instance()->log_data("merge_changes : ipc set ", is_object($this->ipc)? 'true' : 'false'); - if(!$this->ipc) - { - return 0; - } + syncml_logger::get_instance()->log('Begin merge changes'); $sochannel = new syncml_sochannel(); list(, , , $last_merge) = $sochannel->get_channel($this->channel_id); - syncml_logger::get_instance()->log_data("merge_changes last_merge : ", $last_merge); + syncml_logger::get_instance()->log_data('Last merge', $last_merge); + $changed_guids = array_diff( $this->ipc->getIdList($last_merge), $except_list); - syncml_logger::get_instance()->log_data("merge_changes changed_guids : ", $changed_guids); + syncml_logger::get_instance()->log_data( + 'Changed GUIDs', $changed_guids); + foreach($changed_guids as $guid) { - syncml_logger::get_instance()->log_data("merge_changes guid : ", $guid); $this->somappings->update_mapping( $this->channel_id, NULL, $guid, 1); - syncml_logger::get_instance()->log_data("merge_changes update_mapping done for guids : ", $guid); } $sochannel->update_last_merge($this->channel_id); - syncml_logger::get_instance()->log("merge_changes update_last_merge done for ".$this->channel_id); + + syncml_logger::get_instance()->log(sprintf( + 'Merge changes for channel ID %d done', $this->channel_id)); } /** @@ -164,7 +163,7 @@ */ function get_item_by_guid($uri, $type) { - return $this->ipc->getdata($uri, $type); + return syncml_wrap_data($this->ipc->getdata($uri, $type), $type); } /** @@ -203,18 +202,30 @@ */ function replace_item($luid, $data, $type, $override = FALSE) { + syncml_logger::get_instance()->log(sprintf( + 'Replace item %s (%s)', $luid, $type)); + $mappings = $this->somappings->get_mapping( $this->channel_id, $luid, NULL, NULL); + syncml_logger::get_instance()->log_data('Got mappings', $mappings); + $dirty = FALSE; + $guid = NULL; if(count($mappings) > 0) { list(list(,, $guid, $dirty)) = $mappings; } + syncml_logger::get_instance()->log_data('Override is', $override); + syncml_logger::get_instance()->log_data('GUID is', $guid); + syncml_logger::get_instance()->log_data('Dirty is', $dirty); + if(!$override && $dirty) { + syncml_logger::get_instance()->log('Conflict, duplicate it'); + $new_guid = $this->ipc->adddata($data, $type); // we want to add the old item to our client, by @@ -231,6 +242,8 @@ } else if(count($mappings) > 0) { + syncml_logger::get_instance()->log('Replace it'); + $this->ipc->replacedata($guid, $data, $type); $this->somappings->update_mapping( @@ -240,6 +253,8 @@ } else { + syncml_logger::get_instance()->log('Add it'); + $guid = $this->ipc->adddata($data, $type); $this->somappings->insert_mapping( Modified: trunk/syncml/inc/class.syncml_database_devinf.inc.php =================================================================== --- trunk/syncml/inc/class.syncml_database_devinf.inc.php 2008-07-04 16:41:50 UTC (rev 18639) +++ trunk/syncml/inc/class.syncml_database_devinf.inc.php 2008-07-05 21:09:56 UTC (rev 18640) @@ -12,6 +12,8 @@ require_once 'inc/functions.inc.php'; + require_once 'inc/class.xml_parser.inc.php'; + /** * A device information database. */ @@ -36,11 +38,13 @@ switch($uri) { case './devinf10': - return $this->_encode( - $this->_get_devinf_10(), $type, '1.0'); + return syncml_wrap_data( + $this->_encode($this->_get_devinf_10(), $type, '1.0'), + $type); case './devinf11': - return $this->_encode( - $this->_get_devinf_11(), $type, '1.1'); + return syncml_wrap_data( + $this->_encode($this->_get_devinf_11(), $type, '1.1'), + $type); default: return NULL; } @@ -75,9 +79,24 @@ */ function _encode($data, $type, $dtd_version) { + syncml_logger::get_instance()->log("Encoding $type, $dtd_version"); + switch($type) { case 'application/vnd.syncml-devinf+wbxml': + switch($dtd_version) + { + case '1.1': + $doctype = '<!DOCTYPE SyncML PUBLIC "-//SYNCML//DTD SyncML 1.1//EN" "http://www.syncml.org/docs/syncml_represent_v11_20020213.dtd">'; + break; + case '1.0': + default: + $doctype = '<!DOCTYPE SyncML PUBLIC "-//SYNCML//DTD SyncML 1.0//EN" "http://www.syncml.org/docs/syncml_represent_v10_20001207.dtd">'; + } + + return wbxml_encode( + '<?xml version="1.0" encoding="UTF-8"?>' . $doctype . + $data, 0x02, FALSE, FALSE); case 'application/vnd.syncml-devinf+xml': return $data; default: @@ -90,7 +109,7 @@ * * @param $data Data to decode. * @param $type Type of input data. - * @param $dtd_version + * @param $dtd_version * @return string Decoded data in XML array format. */ function _decode($data, $type) @@ -98,7 +117,7 @@ switch($type) { case 'application/vnd.syncml-devinf+wbxml': - $parser = new wbxml_parser(); + $parser = new xml_parser(); return $parser->parse( wbxml_decode($data), new xml_mapper()); case 'application/vnd.syncml-devinf+xml': Modified: trunk/syncml/inc/class.syncml_logger.inc.php =================================================================== --- trunk/syncml/inc/class.syncml_logger.inc.php 2008-07-04 16:41:50 UTC (rev 18639) +++ trunk/syncml/inc/class.syncml_logger.inc.php 2008-07-05 21:09:56 UTC (rev 18640) @@ -22,9 +22,9 @@ function syncml_logger() { $this->handle = fopen(SYNCML_DEBUG_FILE, 'a'); - $this->log_run = substr(md5(microtime()), 0, 4); - if(SYNCML_DEBUG_MODE) { + if(SYNCML_DEBUG_MODE) + { fwrite($this->handle, sprintf("== new run (%s) ==\n", date('H:i:s'))); } @@ -32,7 +32,8 @@ static function get_instance() { - if(is_null(self::$instance)) { + if(is_null(self::$instance)) + { self::$instance = new syncml_logger(); } @@ -41,26 +42,39 @@ function log_data($message, $data) { - if(SYNCML_DEBUG_MODE) { - fwrite($this->handle, sprintf("%s, %s, %s, %s\n", - $this->log_run, date('H:i:s'), $message, + if(SYNCML_DEBUG_MODE) + { + $trace = debug_backtrace(); + $frame = $trace[1]; + + fwrite($this->handle, sprintf("%s::%s(), %s, %s\n", + isset($frame['class']) ? $frame['class'] : '', + isset($frame['function']) ? $frame['function'] : '', + $message, var_export($data, true))); } } - function log_error($errno, $errstr, $errfile, $errline) { - if(SYNCML_DEBUG_MODE) { - fwrite( - $this->handle, - sprintf("%s, error: %s\n", $this->log_run, $errstr)); + function log_error($errno, $errstr, $errfile, $errline) + { + if(SYNCML_DEBUG_MODE) + { + fwrite($this->handle, sprintf("%s (%s:%d)\n", + $errstr, $errfile, $errline)); } } function log($message) { - if(SYNCML_DEBUG_MODE) { - fwrite($this->handle, sprintf("%s, %s, %s\n", - $this->log_run, date('H:i:s'), $message)); + if(SYNCML_DEBUG_MODE) + { + $trace = debug_backtrace(); + $frame = $trace[1]; + + fwrite($this->handle, sprintf("%s::%s(), %s\n", + isset($frame['class']) ? $frame['class'] : '', + isset($frame['function']) ? $frame['function'] : '', + $message)); } } } Modified: trunk/syncml/inc/class.syncml_message.inc.php =================================================================== --- trunk/syncml/inc/class.syncml_message.inc.php 2008-07-04 16:41:50 UTC (rev 18639) +++ trunk/syncml/inc/class.syncml_message.inc.php 2008-07-05 21:09:56 UTC (rev 18640) @@ -81,100 +81,101 @@ if($session->get_var(SYNCML_NOMOREMODIFICATIONS)) { - $open_channels = $session->get_open_channels(); - - $response->set_final(TRUE); + $this->send_modifications_in_each_channel( + $session->get_open_channels(), $session, $response); + } - foreach($open_channels as $open_channel) - { - $database = new syncml_database( - $open_channel['channel_id']); - - if(!$open_channel['server_modifications_sent']) - { - /* - This code is run *after* all modifications from - client are sent and *before* any modfifications - are sent by the server. - */ + // do we have to send a ALERT for more messages? - // LUIDs modified by the *client* during this session - $all_modified_luids = $session->get_all_modified_luids( - $open_channel['channel_id']); + if($response->status_commands_only() && !$response->is_final()) + { + $response->add_alert(SYNCML_ALERT_NEXTMESSAGE, array()); + } - // GUIDs modified by the *client* during this session - $all_modified_guids = $session->get_all_modified_guids( - $open_channel['channel_id']); + // save the anchors if this is last message in session - // Bring all changed items from phpgw - $database->merge_changes($all_modified_guids); + if($response->status_commands_only()) + { + $session->commit_anchors(); + } - switch($open_channel['type']) - { - case SYNCML_ALERT_SLOWSYNC: - $this->prepare_slowsync( - $open_channel['channel_id'], - $all_modified_luids); - break; - case SYNCML_ALERT_REFRESHFROMSERVER: - case SYNCML_ALERT_REFRESHFROMSERVERBYSERVER: - $somappings->delete_mapping( - $open_channel['channel_id'], NULL, NULL, - NULL); - break; - case SYNCML_ALERT_REFRESHFROMCLIENT: - case SYNCML_ALERT_REFRESHFROMCLIENTBYSERVER: - $this->finish_client_refresh( - $open_channel['channel_id'], - $all_client_modified_luids, $database); - break; - } - } + $session->commit(); + } - if(!$open_channel['all_server_modifications_sent']) + function send_modifications_in_each_channel($open_channels, &$session, + &$response) + { + $response->set_final(TRUE); + + foreach($open_channels as $open_channel) + { + $database = new syncml_database($open_channel['channel_id']); + + // is this the first time we send something? + + if(!$open_channel['server_modifications_sent']) + { + $this->prepare_to_send_modifications($open_channel, + $session, $database); + } + + // is there more to send later? + + if(!$open_channel['all_server_modifications_sent']) + { + if($this->send_modifications($response, $session, + $open_channel, $database)) { - $more_to_send = $this->_send_modifications( - $response, $session, $open_channel, $database); + // there is more to send, continue with that in next + // message. + $response->set_final(FALSE); + return; + } + else + { $session->set_open_channel_property( $open_channel['source'], $open_channel['target'], - 'server_modifications_sent', TRUE); - - if($more_to_send) - { - // there's more to send from this channel. we - // continue with that in next message. - - $response->set_final(FALSE); - break; - } - else - { - $session->set_open_channel_property( - $open_channel['source'], - $open_channel['target'], - 'all_server_modifications_sent', TRUE); - } + 'all_server_modifications_sent', TRUE); } } } + } - // do we have to send a ALERT for more messages? + /** + * This code is run *after* all modifications from client are sent and + * *before* any modfifications are sent by the server. + */ + function prepare_to_send_modifications($open_channel, &$session, + &$database) + { + // LUIDs modified by the *client* during this session + $all_modified_luids = $session->get_all_modified_luids( + $open_channel['channel_id']); - if($response->status_commands_only() && !$response->is_final()) - { - $cmdid = $response->add_alert(SYNCML_ALERT_NEXTMESSAGE, - array()); - } + // GUIDs modified by the *client* during this session + $all_modified_guids = $session->get_all_modified_guids( + $open_channel['channel_id']); - // save the anchors if this is last message in session + // Bring all changed items from phpgw + $database->merge_changes($all_modified_guids); - if($response->status_commands_only()) + switch($open_channel['type']) { - $session->commit_anchors(); + case SYNCML_ALERT_SLOWSYNC: + $this->prepare_slowsync($open_channel['channel_id'], + $all_modified_luids); + break; + case SYNCML_ALERT_REFRESHFROMSERVER: + case SYNCML_ALERT_REFRESHFROMSERVERBYSERVER: + $this->prepare_server_refresh($open_channel['channel_id']); + break; + case SYNCML_ALERT_REFRESHFROMCLIENT: + case SYNCML_ALERT_REFRESHFROMCLIENTBYSERVER: + $this->finish_client_refresh($open_channel['channel_id'], + $all_client_modified_luids, $database); + break; } - - $session->commit(); } /** @@ -184,9 +185,13 @@ * @return bool Returns true if there are more modifications to send * that didn't fit in this message. */ - function _send_modifications(&$response, &$session, $open_channel, + function send_modifications(&$response, &$session, $open_channel, $database) { + $session->set_open_channel_property( + $open_channel['source'], $open_channel['target'], + 'server_modifications_sent', TRUE); + switch($open_channel['type']) { case SYNCML_ALERT_SLOWSYNC: @@ -196,8 +201,8 @@ case SYNCML_ALERT_ONEWAYFROMSERVERBYSERVER: case SYNCML_ALERT_REFRESHFROMSERVER: case SYNCML_ALERT_REFRESHFROMSERVERBYSERVER: - return $this->_send_sync(&$response, &$session, $database, - $open_channel); + return $this->add_sync(&$response, &$session, + $database, $open_channel); case SYNCML_ALERT_REFRESHFROMCLIENT: case SYNCML_ALERT_REFRESHFROMCLIENTBYSERVER: case SYNCML_ALERT_ONEWAYFROMCLIENT: @@ -233,9 +238,9 @@ /** * Remove items not touched by the client. - * - * @param $channel_id ID of channel to prepare the slow - * sync for. + * + * @param $channel_id ID of channel to prepare the + * refresh for. * @param $all_client_modified_luids All LUIDs client modified. * @param $database Database involved in this * session. @@ -257,14 +262,26 @@ } /** + * Prepare a refresh from server. + * + * @param $channel_id ID of channel to prepare the refresh for. + */ + function prepare_server_refresh($channel_id) + { + $somappings = new syncml_somappings(); + + $somappings->delete_mapping($channel_id, NULL, NULL, NULL); + } + + /** * Fetch modifications and insert a SYNC command. - * + * * @param $response Response object to write SYNC command to. * @param $session Session object. * @param $database Database object to pull changes from. * @param $open_channel Channel involved in this SYNC command. */ - function _send_sync(&$response, &$session, $database, $open_channel) + function add_sync(&$response, &$session, $database, $open_channel) { $commands = array(); Modified: trunk/syncml/inc/class.syncml_response.inc.php =================================================================== --- trunk/syncml/inc/class.syncml_response.inc.php 2008-07-04 16:41:50 UTC (rev 18639) +++ trunk/syncml/inc/class.syncml_response.inc.php 2008-07-05 21:09:56 UTC (rev 18640) @@ -12,12 +12,6 @@ define('METINF', 'xmlns="syncml:metinf"'); - function ec($cond, $name, $cdata, $attrs = '') - { - return $cond ? ("<$name" . ($attrs ? ' ' . $attrs : '') . - ($cdata === '' ? '/>' : ">$cdata</$name>")) : ''; - } - class syncml_response { var $next_cmdid = 0; @@ -37,12 +31,18 @@ function syncml_response() { - $this->root_namespace = 'SYNCML:SYNCML1.1'; } + static function e($name, $cdata, $attrs = '') + { + return "<$name" . ($attrs ? ' ' . $attrs : '') . + ($cdata === '' ? '/>' : ">$cdata</$name>"); + } + function print_response() { echo '<?xml version="1.0" encoding="UTF-8"?>'; + echo $this->doctype; echo '<SyncML xmlns="', $this->root_namespace, '">'; echo '<SyncHdr>', $this->header, $this->header_cred, '</SyncHdr>'; echo '<SyncBody>', implode('', $this->commands); @@ -129,8 +129,8 @@ '<CmdID>' . $this->get_next_cmdid() . '</CmdID>' . '<MsgRef>' . $msgref . '</MsgRef>' . '<CmdRef>' . $cmdref . '</CmdRef>' . - ec((bool)$srcref, 'SourceRef', $srcref) . - ec((bool)$trgref, 'TargetRef', $trgref) . + ((bool)$srcref ? self::e('SourceRef', $srcref) : '') . + ((bool)$trgref ? self::e('TargetRef', $trgref) : '') . '<Meta>' . $this->get_meta(array('type' => $type)) . '</Meta>' . @@ -150,15 +150,26 @@ '<Alert>' . '<CmdID>' . $this->get_next_cmdid() . '</CmdID>' . '<Data>' . $code . '</Data>' . - ec(is_array($item), 'Item', - $this->get_item($item, $supportlargeobj)) . + (is_array($item) ? self::e('Item', + $this->get_item($item, $supportlargeobj)) : '') . '</Alert>' ); } - + function set_syncml_namespace_version($version) { - $this->root_namespace = 'SYNCML:SYNCML' . $version; + switch($version) + { + case '1.1': + $this->doctype = '<!DOCTYPE SyncML PUBLIC "-//SYNCML//DTD SyncML 1.1//EN" "http://www.syncml.org/ +docs/syncml_represent_v11_20020213.dtd">'; + $this->root_namespace = 'SYNCML:SYNCML1.1'; + break; + case '1.0': + default: + $this->doctype = '<!DOCTYPE SyncML PUBLIC "-//SYNCML//DTD SyncML 1.0//EN" "http://www.syncml.org/docs/syncml_represent_v10_20001207.dtd">'; + $this->root_namespace = 'SYNCML:SYNCML1.0'; + } } function set_header($verdtd, $verproto, $sessionid, $msgid, @@ -171,17 +182,17 @@ '<MsgID>' . $msgid . '</MsgID>' . '<Target>' . '<LocURI>' . $trg_lu . '</LocURI>' . - ec((bool)$trg_ln, "LocName", $trg_ln) . + ((bool)$trg_ln ? self::e('LocName', $trg_ln) : '') . '</Target>' . '<Source>' . '<LocURI>' . $src_lu . '</LocURI>' . - ec((bool)$src_ln, "LocName", $src_ln) . + ((bool)$src_ln ? self::e('LocName', $src_ln) : '') . '</Source>'; } function set_header_cred($format, $type, $data) { - $this->header_cred = + $this->header_cred = '<Cred>' . '<Meta>' . '<Format xmlns="syncml:metinf">' . @@ -204,48 +215,53 @@ '<CmdRef>' . $cmdref . '</CmdRef>' . '<Cmd>' . $cmd . '</Cmd>' . '<MsgRef>' . $msgref . '</MsgRef>' . - ec((bool)$srcref, 'SourceRef', $srcref) . - ec((bool)$trgref, 'TargetRef', $trgref) . + ((bool)$srcref ? self::e('SourceRef', $srcref) : '') . + ((bool)$trgref ? self::e('TargetRef', $trgref) : '') . '<Data>' . $data . '</Data>' . - ec(is_array($item), "Item", $this->get_item($item)) . + (is_array($item) ? self::e('Item', + $this->get_item($item)) : '') . '</Status>' ); } + /** + * Build "item" XML node. + * + * @param $item array Array of elements in the node. + * @return string The item XML node. + */ function get_item($item) { return - ec(isset($item['trg_uri']), "Target", - '<LocURI>' . @$item['trg_uri'] . '</LocURI>' . - ec(isset($item['trg_name']), "LocName", - @$item['trg_name'])) . - ec(isset($item['src_uri']), "Source", + (isset($item['trg_uri']) ? self::e('Target', + '<LocURI>' . $item['trg_uri'] . '</LocURI>' . + (isset($item['trg_name']) ? self::e('LocName', + $item['trg_name']) : '')) : '') . + (isset($item['src_uri']) ? self::e('Source', '<LocURI>' . @$item['src_uri'] . '</LocURI>' . - ec(isset($item['src_name']), "LocName", - @$item['src_name'])) . - ec(isset($item['meta']), 'Meta', - @$this->get_meta($item['meta'])) . - ec(isset($item['data']), 'Data', - /* '<![CDATA[' . */ @$item['data'] /* . ']]>' */) . - ec(isset($item['moredata']) && $item['moredata'], - 'MoreData', ''); + (isset($item['src_name']) ? self::e('LocName', + $item['src_name']) : '')) : '') . + (isset($item['meta']) ? self::e('Meta', + $this->get_meta($item['meta'])) : '') . + (isset($item['data']) ? self::e('Data', + /* '<![CDATA[' . */ @$item['data'] /* . ']]>' */) : '') . + ((isset($item['moredata']) && $item['moredata']) ? + self::e('MoreData', '') : ''); } function get_meta($meta) { return - ec(isset($meta['type']), 'Type', @$meta['type'], METINF) . - ec( - isset($meta['next']), - 'Anchor', + (isset($meta['type']) ? + self::e('Type', $meta['type'], METINF) : '') . + (isset($meta['next']) ? self::e('Anchor', '<Next>' . @$meta['next'] . '</Next>' . - ec(isset($meta['last']), 'Last', @$meta['last']), - METINF - ) . - ec(isset($meta['maxobjsize']), 'MaxObjSize', - @$meta['maxobjsize'], METINF) . - ec(isset($meta['size']) && $meta['size'], 'Size', - @$meta['size'], METINF); + (isset($meta['last']) ? self::e('Last', $meta['last'], + METINF) : ''), METINF) : '') . + (isset($meta['maxobjsize']) ? + self::e('MaxObjSize', $meta['maxobjsize'], METINF) : '') . + (isset($meta['size']) ? + self::e('Size', $meta['size'], METINF) : ''); } function add_status_with_chal($cmdref, $msgref, $cmd, $trgref, @@ -259,8 +275,8 @@ '<CmdRef>' . $cmdref . '</CmdRef>' . '<Cmd>' . $cmd . '</Cmd>' . '<MsgRef>' . $msgref . '</MsgRef>' . - ec($srcref, 'SourceRef', $srcref) . - ec($trgref, 'TargetRef', $trgref) . + ((bool)$srcref ? self::e('SourceRef', $srcref) : '') . + ((bool)$trgref ? self::e('TargetRef', $trgref) : '') . '<Data>' . $data . '</Data>' . '<Chal>' . '<Meta>' . @@ -268,8 +284,8 @@ $type . '</Type>' . '<Format xmlns="syncml:metinf">b64</Format>' . - ec($nonce, 'NextNonce', base64_encode($nonce), - METINF) . + ($nonce ? self::e('NextNonce', + base64_encode($nonce), METINF) : '') . '</Meta>' . '</Chal>' . '</Status>' @@ -287,8 +303,8 @@ '<CmdRef>' . $cmdref . '</CmdRef>' . '<Cmd>' . $cmd . '</Cmd>' . '<MsgRef>' . $msgref . '</MsgRef>' . - ec($srcref, 'SourceRef', $srcref) . - ec($trgref, 'TargetRef', $trgref) . + ((bool)$srcref ? self::e('SourceRef', $srcref) : '') . + ((bool)$trgref ? self::e('TargetRef', $trgref) : '') . '<Data>' . $data . '</Data>' . '<Item>' . '<Data>' . @@ -309,7 +325,7 @@ '<Meta>' . $this->get_meta($meta) . '</Meta>' . '<Item>' . $this->get_item($item) . - ec(!$last_chunk, 'MoreData', '') . + (!$last_chunk ? self::e('MoreData', '') : '') . '</Item>' . '</Add>'; } @@ -331,7 +347,7 @@ '<Meta>' . $this->get_meta($meta) . '</Meta>' . '<Item>' . $this->get_item($item) . - ec(!$last_chunk, 'MoreData', '') . + (!$last_chunk ? self::e('MoreData', '') : '') . '</Item>' . '</Replace>'; } @@ -348,8 +364,8 @@ '<Source>' . '<LocURI>' . $src_uri . '</LocURI>' . '</Source>' . - ec($supportnbrofchanges, 'NumberOfChanges', - $nbrofchanges) . + ($supportnbrofchanges ? self::e('NumberOfChanges', + $nbrofchanges) : '') . implode('', $commands) . '</Sync>' ); Modified: trunk/syncml/inc/functions.inc.php =================================================================== --- trunk/syncml/inc/functions.inc.php 2008-07-04 16:41:50 UTC (rev 18639) +++ trunk/syncml/inc/functions.inc.php 2008-07-05 21:09:56 UTC (rev 18640) @@ -56,7 +56,7 @@ * Parse the XML definition and look for encoding attribute. * * @param $data XML string. - * @return string Found encoding or NULL of no encoding found. + * @return string Found encoding or NULL of no encoding found. */ function syncml_parse_encoding($data) { @@ -64,7 +64,31 @@ { return strtoupper($m[1]); } - + return NULL; } + + /** + * Wrap data with CDATA tags if necessary. + * + * @param $data + * @param $type + * @return string + */ + function syncml_wrap_data($data, $type) + { + $types = array + ( + 'text/calendar' => TRUE, + 'text/x-vcalendar' => TRUE, + 'text/plain' => TRUE, + 'text/x-vcard' => TRUE, + 'text/vcard' => TRUE, + 'application/vnd.syncml-devinf+wbxml' => TRUE, + 'application/vnd.syncml-devinf+xml' => FALSE + ); + + return (isset($types[$type]) && $types[$type]) ? + '<![CDATA[' . $data . ']]>' : $data; + } ?> Modified: trunk/syncml/syncml.php =================================================================== --- trunk/syncml/syncml.php 2008-07-04 16:41:50 UTC (rev 18639) +++ trunk/syncml/syncml.php 2008-07-05 21:09:56 UTC (rev 18640) @@ -28,16 +28,13 @@ require_once 'inc/class.xml_parser.inc.php'; require_once 'inc/class.xml_offset_mapper.inc.php'; - require_once 'inc/class.syncml_wbxml_parser.inc.php'; - require_once 'inc/class.syncml_wbxml_response.inc.php'; - require_once 'inc/class.syncml_response.inc.php'; require_once 'inc/class.syncml_message.inc.php'; $file_date = gettimeofday(true); // this is a ugly, ugly hack - //$GLOBALS['phpgw']->db->query('TRUNCATE phpgw_access_log'); + $GLOBALS['phpgw']->db->query('TRUNCATE phpgw_access_log'); set_error_handler(array(syncml_logger::get_instance(), 'log_error'), E_ALL); @@ -51,13 +48,13 @@ $post_input = implode("\r\n", file('php://input')); - file_put_contents( - sprintf("%s/%s-input.xml", SYNCML_LOG_DIR, $file_date), - $post_input . "\n"); - switch($_SERVER['CONTENT_TYPE']) { case 'application/vnd.syncml+wbxml': + file_put_contents( + sprintf("%s/%s-input.wbxml", SYNCML_LOG_DIR, $file_date), + $post_input . "\n"); + $post_input = wbxml_decode($post_input); case 'application/vnd.syncml+xml': $parser = new xml_parser(); @@ -67,6 +64,10 @@ exit('I\'m a SyncML server (2)'); } + file_put_contents( + sprintf("%s/%s-input.xml", SYNCML_LOG_DIR, $file_date), + $post_input . "\n"); + $message = new syncml_message(); // the header @@ -96,13 +97,17 @@ if($_SERVER['CONTENT_TYPE'] == 'application/vnd.syncml+wbxml') { + /* // remove the xml declaration tag $xml = substr(ob_get_clean(), 38); + */ - ob_start(); + // replace some bogus FPI values + /* + I don't remember why this hack was needed. It appears to work without + it. - // replace some bogus FPI values - echo str_replace( + $wbxml = str_replace( array( chr(0x02) . chr(0xA4) . chr(0x01) . chr(0x6A), chr(0x02) . chr(0xA4) . chr(0x02) . chr(0x6A)), @@ -111,6 +116,17 @@ chr(0x02) . chr(0x9F) . chr(0x52) . chr(0x6A)), wbxml_encode($xml, 0x02, FALSE, FALSE) ); + */ + + $wbxml = wbxml_encode(ob_get_clean(), 0x02, FALSE, FALSE); + + ob_start(); + + file_put_contents( + sprintf("%s/%s-output.wbxml", SYNCML_LOG_DIR, $file_date), + $wbxml); + + echo $wbxml; } header('Content-Type: ' . $_SERVER['CONTENT_TYPE']); _______________________________________________ phpGroupWare-cvs mailing list phpGroupWare-cvs@gnu.org http://lists.gnu.org/mailman/listinfo/phpgroupware-cvs