[sync] Hack to enable Funambol 6.5 to sync with Horde 4

Christian Bomhardt horde at bomhardt.de
Tue Nov 15 20:59:54 UTC 2011


Hi,

in the meantime, I patched my Horde 4 and now I am able to sync at least 
from Server to Phone (this is the only direction I use). IMHO, Horde 4 
sync is not yet as good as 3.x was  - at least I found several issues. 
My patch is probably not the most elegant, but at least with as less 
changes as possible - if the  corrections don't make it into the offical 
codeline, i don't have to re-apply too many corrections after update...

Maybe this helps someone - it took me quite a few weeks to figure this 
out...

Kind Regards,
Christian

Fixes required in ../PEAR/Horde/Syncml/Device/*Sync4j.php*
Adjust *vevent2sif* to not die in case of more than one component:

         default:
             //Added code - in case of multiple, take first one and log 
related entry - not perfect, but working
             $content = $components[0];
             Horde::logMessage('Sync4j:vevent2sif: multiple components ! 
' . $vcard,'ERR');
             break;

             //OLD CODE
             // @TODO: NEVER use die() in a library.
             // die("Multiple components found; only one is supported.");

Add lines to *convertServer2Client:*
     public function convertServer2Client($content, $contentType, $database)
     {
         $database = $GLOBALS['backend']->normalize($database);

//cbo ADDED
        if(substr($contentType,0,14) == 'text/x-s4j-sif')
           {
           $l = "\nOutput converted for Funambol client 
($contentType):\n" . $content . "\n";
           
$GLOBALS['backend']->logFile(Horde_SyncMl_Backend::LOGFILE_DATA, $l);
           return array(base64_encode($content),$contentType,'b64');
           }
//cbo ADDED END

These fixes are required to be able to return Funambol Data from APIs 
and improve (still not perfect) behavior of conversion in some special 
situations (for me, only 1 / xxxx calendar entries produced this issue)

All remaining fixes in lib/API of corresponding applications to return 
Funambol supported content in export function.

*MNemo (Notes):*
Add method getChanges() (copied from Turba, and works perfect) to 
lib/Api.php

/**
      * Method for obtaining all server changes between two timestamps. 
Basically
      * a wrapper around listBy(), but returns an array containing all adds,
      * edits and deletions.
      *
      * @param integer $start             The starting timestamp
      * @param integer $end               The ending timestamp.
      *
      * @return array  An hash with 'add', 'modify' and 'delete' arrays.
      */
     public function getChanges($start, $end)
     {
         return array('add' => $this->listBy('add', $start, null, $end),
                      'modify' => $this->listBy('modify', $start, null, 
$end),
                      'delete' => $this->listBy('delete', $start, null, 
$end));
     }

Enhance export function:
Add new switch statement:
        switch ($contentType) {
         case 'text/x-s4j-sifn':
             $a=array('Body' => $memo['body'],'Categories' => 
$memo['category'],
              'Subject' => Mnemo_Driver::getMemoDescription($memo['body']));
             return Horde_SyncMl_Device_sync4j::array2sif($a, '<note>', 
'</note>');

*Turba/API.php*
In fucntion export:
             $version = '3.0';
             list($contentType,) = explode(';', $contentType);
             switch ($contentType) {
             case 'text/x-vcard':
                 $version = '2.1';
*==>insert after this line (in case your mobile supports different 
fields, adjust accordingly)*
             case 'text/x-s4j-sifc': //###cbo
                  $contentType='text/vcard';

                 $attributes = array();
                 foreach ($result->objects as $object)
                    {
                     foreach ($cfgSources[$source]['map'] as $field => 
$map)
                        {
                        $attributes[$field] = $object->getValue($field);
                        }
                    }
                  $a=array('Anniversary' => 
$object->getValue('anniversary'),
                  'AssistantName' => '',
                  'AssistantTelephoneNumber' => '',
                  'Birthday' => $object->getValue('birthday'),
                  'Body' => '',
                  'Business2TelephoneNumber' => '',
                  'BusinessAddressCity' => $object->getValue('workCity'),
                  'BusinessAddressCountry' => 
$object->getValue('workCountry'),
                  'BusinessAddressPostalCode' => 
$object->getValue('workPostalCode'),
                  'BusinessAddressState' => 
$object->getValue('workProvince'),
                  'BusinessAddressStreet' => 
$object->getValue('workStreet'),
                  'BusinessFaxNumber' => str_replace('/',' 
',$object->getValue('fax')),
                  'BusinessTelephoneNumber' => str_replace('/',' 
',$object->getValue('workPhone')),
                  'CarTelephoneNumber' => str_replace('/',' 
',$object->getValue('cellPhone')),
                  'Categories' => $object->getValue('category'),
                  'Children' => '',
                  'CompanyMainTelephoneNumber' => '',
                  'CompanyName' => $object->getValue('company'),
                  'CustomerID' => '',
                  'Department' => $object->getValue('department'),
                  'Email1Address' => $object->getValue('workEmail'),
                  'Email2Address' => $object->getValue('email'),
                  'Email3Address' => '',
                  'FileAs' => $object->getValue('name'),
                  'FirstName' => $object->getValue('firstname'),
                  'GovernmentIDNumber' => '',
                  'Home2TelephoneNumber' => '',
                  'HomeAddressCity' => $object->getValue('homeCity'),
                  'HomeAddressCountry' => $object->getValue('homeCountry'),
                  'HomeAddressPostalCode' => 
$object->getValue('homePostalCode'),
                  'HomeAddressState' => '',
                  'HomeAddressStreet' => $object->getValue('homeStreet'),
                  'HomeFaxNumber' => str_replace('/',' 
',$object->getValue('homeFax')),
                  'HomeTelephoneNumber' => str_replace('/',' 
',$object->getValue('homePhone')),
                  'IM2Address' => '',
                  'IM3Address' => '',
                  'IMAddress' => '',
                  'JobTitle' => $object->getValue('title'),
                  'LastName' => $object->getValue('lastname'),
                  'ManagerName' => '',
                  'MiddleName' => '',
                  'MobileTelephoneNumber' => str_replace('/',' 
',$object->getValue('workCellPhone')),
                  'NickName' => '',
                  'OfficeLocation' => '',
                  'OtherAddressCity' => '',
                  'OtherAddressCountry' => '',
                  'OtherAddressPostalCode' => '',
                  'OtherAddressState' => '',
                  'OtherAddressStreet' => '',
                  'PagerNumber' => '',
                  'Photo' => '',
                  'RadioTelephoneNumber' => '',
                  'Spouse' => $object->getValue('spouse'),
                  'Suffix' => $object->getValue('nameSuffix'),
                  'Title' => $object->getValue('title'),
                  'WebPage' => $object->getValue('website'),
                  'YomiCompanyName' => '',
                  'YomiFirstName' => '',
                  'YomiLastName' => '',
                  );
                  return Horde_SyncMl_Device_sync4j::array2sif($a,'<?xml 
version="1.0"?><contact>','</contact>');


*NAG:*
/lib/Api.php

Add to function export addtional case:

         case 'text/x-s4j-sift': //cbo ###
             // Create the new iCalendar container.
             $iCal = new Horde_Icalendar($version);
             $iCal->setAttribute('PRODID', '-//The Horde Project//Nag ' 
. $GLOBALS['registry']->getVersion() . '//EN');
             $iCal->setAttribute('METHOD', 'PUBLISH');

             // Create new vTodo object.
             $vTodo = $task->toiCalendar($iCal);
             $vTodo->setAttribute('VERSION', $version);

             $iCal->addComponent($vTodo);
             return 
Horde_SyncMl_Device_sync4j::vtodo2sif($iCal->exportvCalendar());

*KRONOLITH*:
/lib/Api.php

Add to function export addtional case:

         switch ($contentType)
         {
         case 'text/x-s4j-sife': //cbo ###
             $iCal = new Horde_Icalendar('2.0');
             // Create a new vEvent.
             $iCal->addComponent($event->toiCalendar($iCal));

             
$calStr=Horde_SyncMl_Device_sync4j::vevent2sif($iCal->exportvCalendar());
             return $calStr;



More information about the sync mailing list