/** * Convert the content. */ public function convertClient2Server($content, $contentType) { list($content, $contentType) = parent::convertClient2Server($content, $contentType); switch ($contentType) { case 'text/x-s4j-sifn': case 'text/x-sifn': $content = Horde_SyncMl_Device_sync4j::sif2vnote($content); $contentType = 'text/x-vnote'; break; case 'text/x-s4j-sifc': case 'text/x-sifc': $content = Horde_SyncMl_Device_sync4j::sif2vcard($content); $contentType = 'text/x-vcard'; break; case 'text/x-s4j-sife': case 'text/x-sife': $content = Horde_SyncMl_Device_sync4j::sif2vevent($content); $contentType = 'text/calendar'; break; case 'text/x-s4j-sift': case 'text/x-sift': $content = Horde_SyncMl_Device_sync4j::sif2vtodo($content); $contentType = 'text/calendar'; break; case 'text/calendar': case 'text/x-vcalendar': $si = $GLOBALS['backend']->state->sourceURI; if (stristr($si, 'fol-') !== false) { // The Funambol Outlook connector uses invalid STATUS // values. Actually it maps MeetingStatus values of the // Outlook event to the STATUS property, which is // completely useless. So drop the STATUS altogether. $content = preg_replace('/^STATUS:.*\\r?\\n/im', '', $content); } break; } $GLOBALS['backend']->logFile(Horde_SyncMl_Backend::LOGFILE_DATA, "\nInput converted for server ({$contentType}):\n{$content}\n"); return array($content, $contentType); }
/** * When a test case contains adds/modifies/deletes being sent to the server, * these changes must be extracted from the test data and manually performed * using the api to achieve the desired behaviour by the server * * @throws Horde_Exception */ function testPre($name, $number) { global $debuglevel; $ref0 = getClient($name, $number); // Extract database (in horde: service). if (preg_match('|<Alert>.*?<Target>\\s*<LocURI>([^>]*)</LocURI>.*?</Alert>|si', $ref0, $m)) { $GLOBALS['service'] = $m[1]; } if (!preg_match('|<SyncHdr>.*?<Source>\\s*<LocURI>(.*?)</LocURI>.*?</SyncHdr>|si', $ref0, $m)) { echo $ref0; throw new Horde_Exception('Unable to find device id'); } $device_id = $m[1]; // Start backend session if not already done. if ($GLOBALS['testbackend']->getSyncDeviceID() != $device_id) { $GLOBALS['testbackend']->sessionStart($device_id, null, Horde_SyncMl_Backend::MODE_TEST); } // This makes a login even when a logout has occured when the session got // deleted. $GLOBALS['testbackend']->setUser(SYNCMLTEST_USERNAME); $ref1 = getServer($name, $number + 1); if (!$ref1) { return; } $ref1 = str_replace(array('<![CDATA[', ']]>', '<?xml version="1.0"?><!DOCTYPE SyncML PUBLIC "-//SYNCML//DTD SyncML 1.1//EN" "http://www.syncml.org/docs/syncml_represent_v11_20020213.dtd">'), '', $ref1); // Check for Adds. if (preg_match_all('|<Add>.*?<type[^>]*>(.*?)</type>.*?<LocURI[^>]*>(.*?)</LocURI>.*?<data[^>]*>(.*?)</data>.*?</Add|si', $ref1, $m, PREG_SET_ORDER)) { foreach ($m as $c) { list(, $contentType, $locuri, $data) = $c; // Some Sync4j tweaking. switch (Horde_String::lower($contentType)) { case 'text/x-s4j-sifn': $data = Horde_SyncMl_Device_sync4j::sif2vnote(base64_decode($data)); $contentType = 'text/x-vnote'; $service = 'notes'; break; case 'text/x-s4j-sifc': $data = Horde_SyncMl_Device_sync4j::sif2vcard(base64_decode($data)); $contentType = 'text/x-vcard'; $service = 'contacts'; break; case 'text/x-s4j-sife': $data = Horde_SyncMl_Device_sync4j::sif2vevent(base64_decode($data)); $contentType = 'text/calendar'; $service = 'calendar'; break; case 'text/x-s4j-sift': $data = Horde_SyncMl_Device_sync4j::sif2vtodo(base64_decode($data)); $contentType = 'text/calendar'; $service = 'tasks'; break; case 'text/x-vcalendar': case 'text/calendar': if (preg_match('/(\\r\\n|\\r|\\n)BEGIN:\\s*VTODO/', $data)) { $service = 'tasks'; } else { $service = 'calendar'; } break; default: throw new Horde_Exception("Unable to find service for contentType={$contentType}"); } $result = $GLOBALS['testbackend']->addEntry($service, $data, $contentType); if (is_a($result, 'PEAR_Error')) { echo "error importing data into {$service}:\n{$data}\n"; throw new Horde_Exception_Wrapped($result); } if ($debuglevel >= 2) { echo "simulated {$service} add of {$result} as {$locuri}!\n"; echo ' at ' . date('Y-m-d H:i:s') . "\n"; if ($debuglevel >= 10) { echo "data: {$data}\nsuid={$result}\n"; } } // Store UID used by server. $GLOBALS['mapping_locuri2uid'][$locuri] = $result; } } // Check for Replaces. if (preg_match_all('|<Replace>.*?<type[^>]*>(.*?)</type>.*?<LocURI[^>]*>(.*?)</LocURI>.*?<data[^>]*>(.*?)</data>.*?</Replace|si', $ref1, $m, PREG_SET_ORDER)) { foreach ($m as $c) { list(, $contentType, $locuri, $data) = $c; // Some Sync4j tweaking. switch (Horde_String::lower($contentType)) { case 'sif/note': case 'text/x-s4j-sifn': $data = Horde_SyncMl_Device_sync4j::sif2vnote(base64_decode($data)); $contentType = 'text/x-vnote'; $service = 'notes'; break; case 'sif/contact': case 'text/x-s4j-sifc': $data = Horde_SyncMl_Device_sync4j::sif2vcard(base64_decode($data)); $contentType = 'text/x-vcard'; $service = 'contacts'; break; case 'sif/calendar': case 'text/x-s4j-sife': $data = Horde_SyncMl_Device_sync4j::sif2vevent(base64_decode($data)); $contentType = 'text/calendar'; $service = 'calendar'; break; case 'sif/task': case 'text/x-s4j-sift': $data = Horde_SyncMl_Device_sync4j::sif2vtodo(base64_decode($data)); $contentType = 'text/calendar'; $service = 'tasks'; break; case 'text/x-vcalendar': case 'text/calendar': if (preg_match('/(\\r\\n|\\r|\\n)BEGIN:\\s*VTODO/', $data)) { $service = 'tasks'; } else { $service = 'calendar'; } break; default: throw new Horde_Exception("Unable to find service for contentType={$contentType}"); } /* Get SUID. */ $suid = $GLOBALS['testbackend']->getSuid($service, $locuri); if (empty($suid)) { throw new Horde_Exception("Unable to find SUID for CUID {$locuri} for simulating replace"); } $result = $GLOBALS['testbackend']->replaceEntry($service, $data, $contentType, $suid); if (is_a($result, 'PEAR_Error')) { echo "Error replacing data {$locuri} suid={$suid}!\n"; throw new Horde_Exception_Wrapped($result); } if ($debuglevel >= 2) { echo "simulated {$service} replace of {$locuri} suid={$suid}!\n"; if ($debuglevel >= 10) { echo "data: {$data}\nnew id={$result}\n"; } } } } // Check for Deletes. // <Delete><CmdID>5</CmdID><Item><Target><LocURI>1798147</LocURI></Target></Item></Delete> if (preg_match_all('|<Delete>.*?<Target>\\s*<LocURI>(.*?)</LocURI>|si', $ref1, $m, PREG_SET_ORDER)) { foreach ($m as $d) { list(, $locuri) = $d; /* Get SUID. */ $service = $GLOBALS['service']; $suid = $GLOBALS['testbackend']->getSuid($service, $locuri); if (empty($suid)) { // Maybe we have a handletaskincalendar. if ($service == 'calendar') { if ($debuglevel >= 2) { echo "special tasks delete...\n"; } $service = 'tasks'; $suid = $GLOBALS['testbackend']->getSuid($service, $locuri); } } if (empty($suid)) { throw new Horde_Exception("Unable to find SUID for CUID {$locuri} for simulating {$service} delete"); } $result = $GLOBALS['testbackend']->deleteEntry($service, $suid); // @TODO: simulate a delete by just faking some history data. if (is_a($result, 'PEAR_Error')) { echo "Error deleting data {$locuri}!"; throw new Horde_Exception_Wrapped($result); } if ($debuglevel >= 2) { echo "simulated {$service} delete of {$suid}!\n"; } } } }