Back to index

d-push  2.0
Public Member Functions | Private Attributes
ExportChangesICS Class Reference

This is our ICS exporter which requests the actual exporter from ICS and makes sure that the ImportProxies are used. More...

Inheritance diagram for ExportChangesICS:
Inheritance graph
[legend]
Collaboration diagram for ExportChangesICS:
Collaboration graph
[legend]

List of all members.

Public Member Functions

 ExportChangesICS ($session, $store, $folderid=false)
 Constructor.
 Config ($state, $flags=0)
 Configures the exporter.
 ConfigContentParameters ($contentparameters)
 Configures additional parameters used for content synchronization.
 InitializeExporter (&$importer)
 Sets the importer the exporter will sent it's changes to and initializes the Exporter.
 GetState ()
 Reads the current state from the Exporter.
 GetChangeCount ()
 Returns the amount of changes to be exported.
 Synchronize ()
 Synchronizes a change.

Private Attributes

 $folderid
 $store
 $session
 $restriction
 $contentparameters
 $flags
 $exporterflags
 $exporter

Detailed Description

This is our ICS exporter which requests the actual exporter from ICS and makes sure that the ImportProxies are used.

Definition at line 56 of file exporter.php.


Member Function Documentation

ExportChangesICS::Config ( state,
flags = 0 
)

Configures the exporter.

Parameters:
string$state
int$flagspublic
Returns:
boolean
Exceptions:
StatusException

Implements IChanges.

Definition at line 125 of file exporter.php.

                                               {
        $this->exporterflags = 0;
        $this->flags = $flags;

        // this should never happen
        if ($this->exporter === false || is_array($state))
            throw new StatusException("ExportChangesICS->Config(): Error, exporter not available", SYNC_FSSTATUS_CODEUNKNOWN, null, LOGLEVEL_ERROR);

        // change exporterflags if we are doing a ContentExport
        if($this->folderid) {
            $this->exporterflags |= SYNC_NORMAL | SYNC_READ_STATE;

            // Initial sync, we don't want deleted items. If the initial sync is chunked
            // we check the change ID of the syncstate (0 at initial sync)
            // On subsequent syncs, we do want to receive delete events.
            if(strlen($state) == 0 || bin2hex(substr($state,4,4)) == "00000000") {
                if (!($this->flags & BACKEND_DISCARD_DATA))
                    ZLog::Write(LOGLEVEL_DEBUG, "ExportChangesICS->Config(): synching inital data");
                $this->exporterflags |= SYNC_NO_SOFT_DELETIONS | SYNC_NO_DELETIONS;
            }
        }

        if($this->flags & BACKEND_DISCARD_DATA)
            $this->exporterflags |= SYNC_CATCHUP;

        // Put the state information in a stream that can be used by ICS
        $stream = mapi_stream_create();
        if(strlen($state) == 0)
            $state = hex2bin("0000000000000000");

        if (!($this->flags & BACKEND_DISCARD_DATA))
            ZLog::Write(LOGLEVEL_DEBUG, sprintf("ExportChangesICS->Config() initialized with state: 0x%s", bin2hex($state)));

        mapi_stream_write($stream, $state);
        $this->statestream = $stream;
    }

Here is the call graph for this function:

Configures additional parameters used for content synchronization.

Parameters:
ContentParameters$contentparameterspublic
Returns:
boolean
Exceptions:
StatusException

Implements IExportChanges.

Definition at line 171 of file exporter.php.

                                                               {
        $filtertype = $contentparameters->GetFilterType();
        switch($contentparameters->GetContentClass()) {
            case "Email":
                $this->restriction = ($filtertype || !Utils::CheckMapiExtVersion('7')) ? MAPIUtils::GetEmailRestriction(Utils::GetCutOffDate($filtertype)) : false;
                break;
            case "Calendar":
                $this->restriction = ($filtertype || !Utils::CheckMapiExtVersion('7')) ? MAPIUtils::GetCalendarRestriction($this->store, Utils::GetCutOffDate($filtertype)) : false;
                break;
            default:
            case "Contacts":
            case "Tasks":
                $this->restriction = false;
                break;
        }

        $this->contentParameters = $contentparameters;
    }

Here is the call graph for this function:

ExportChangesICS::ExportChangesICS ( session,
store,
folderid = false 
)

Constructor.

Parameters:
mapisession$session
mapistore$store
string(opt)

public

Exceptions:
StatusException

Definition at line 76 of file exporter.php.

                                                                          {
        // Open a hierarchy or a contents exporter depending on whether a folderid was specified
        $this->session = $session;
        $this->folderid = $folderid;
        $this->store = $store;
        $this->restriction = false;

        try {
            if($folderid) {
                $entryid = mapi_msgstore_entryidfromsourcekey($store, $folderid);
            }
            else {
                $storeprops = mapi_getprops($this->store, array(PR_IPM_SUBTREE_ENTRYID));
                $entryid = $storeprops[PR_IPM_SUBTREE_ENTRYID];
            }

            $folder = false;
            if ($entryid)
                $folder = mapi_msgstore_openentry($this->store, $entryid);

            // Get the actual ICS exporter
            if($folderid) {
                if ($folder)
                    $this->exporter = mapi_openproperty($folder, PR_CONTENTS_SYNCHRONIZER, IID_IExchangeExportChanges, 0 , 0);
                else
                    $this->exporter = false;
            }
            else {
                $this->exporter = mapi_openproperty($folder, PR_HIERARCHY_SYNCHRONIZER, IID_IExchangeExportChanges, 0 , 0);
            }
        }
        catch (MAPIException $me) {
            $this->exporter = false;
            // We return the general error SYNC_FSSTATUS_CODEUNKNOWN (12) which is also SYNC_STATUS_FOLDERHIERARCHYCHANGED (12)
            // if this happened while doing content sync, the mobile will try to resync the folderhierarchy
            throw new StatusException(sprintf("ExportChangesICS('%s','%s','%s'): Error, unable to open folder: 0x%X", $session, $store, Utils::PrintAsString($folderid), mapi_last_hresult()), SYNC_FSSTATUS_CODEUNKNOWN);
        }
    }

Here is the call graph for this function:

Returns the amount of changes to be exported.

public

Returns:
int

Implements IExportChanges.

Definition at line 278 of file exporter.php.

                                      {
        if ($this->exporter)
            return mapi_exportchanges_getchangecount($this->exporter);
        else
            return 0;
    }

Reads the current state from the Exporter.

public

Returns:
string
Exceptions:
StatusException

Implements IChanges.

Definition at line 250 of file exporter.php.

                               {
        $error = false;
        if(!isset($this->statestream) || $this->exporter === false)
            $error = true;

        if($error === true || mapi_exportchanges_updatestate($this->exporter, $this->statestream) != true )
            throw new StatusException(sprintf("ExportChangesICS->GetState(): Error, state not available or unable to update: 0x%X", mapi_last_hresult()), (($this->folderid)?SYNC_STATUS_FOLDERHIERARCHYCHANGED:SYNC_FSSTATUS_CODEUNKNOWN), null, LOGLEVEL_WARN);

        mapi_stream_seek($this->statestream, 0, STREAM_SEEK_SET);

        $state = "";
        while(true) {
            $data = mapi_stream_read($this->statestream, 4096);
            if(strlen($data))
                $state .= $data;
            else
                break;
        }

        return $state;
    }

Sets the importer the exporter will sent it's changes to and initializes the Exporter.

Parameters:
object&$importerImplementation of IImportChanges

public

Returns:
boolean
Exceptions:
StatusException

Implements IExportChanges.

Definition at line 201 of file exporter.php.

                                                   {
        // Because we're using ICS, we need to wrap the given importer to make it suitable to pass
        // to ICS. We do this in two steps: first, wrap the importer with our own PHP importer class
        // which removes all MAPI dependency, and then wrap that class with a C++ wrapper so we can
        // pass it to ICS

        // this should never happen!
        if($this->exporter === false || !isset($this->statestream) || !isset($this->flags) || !isset($this->exporterflags) ||
            ($this->folderid && !isset($this->contentParameters)) )
            throw new StatusException("ExportChangesICS->InitializeExporter(): Error, exporter or essential data not available", SYNC_FSSTATUS_CODEUNKNOWN, null, LOGLEVEL_ERROR);

        // PHP wrapper
        $phpwrapper = new PHPWrapper($this->session, $this->store, $importer);

        // with a folderid we are going to get content
        if($this->folderid) {
            $phpwrapper->ConfigContentParameters($this->contentParameters);

            // ICS c++ wrapper
            $mapiimporter = mapi_wrap_importcontentschanges($phpwrapper);
            $includeprops = false;
        }
        else {
            $mapiimporter = mapi_wrap_importhierarchychanges($phpwrapper);
            $includeprops = array(PR_SOURCE_KEY, PR_DISPLAY_NAME);
        }

        if (!$mapiimporter)
            throw new StatusException(sprintf("ExportChangesICS->InitializeExporter(): Error, mapi_wrap_import_*_changes() failed: 0x%X", mapi_last_hresult()), SYNC_FSSTATUS_CODEUNKNOWN, null, LOGLEVEL_WARN);

        $ret = mapi_exportchanges_config($this->exporter, $this->statestream, $this->exporterflags, $mapiimporter, $this->restriction, $includeprops, false, 1);
        if(!$ret)
            throw new StatusException(sprintf("ExportChangesICS->InitializeExporter(): Error, mapi_exportchanges_config() failed: 0x%X", mapi_last_hresult()), SYNC_FSSTATUS_CODEUNKNOWN, null, LOGLEVEL_WARN);

        $changes = mapi_exportchanges_getchangecount($this->exporter);
        if($changes || !($this->flags & BACKEND_DISCARD_DATA))
            ZLog::Write(LOGLEVEL_DEBUG, sprintf("ExportChangesICS->InitializeExporter() successfully. %d changes ready to sync.", $changes));

        return $ret;
    }

Here is the call graph for this function:

Synchronizes a change.

public

Returns:
array

Implements IExportChanges.

Definition at line 291 of file exporter.php.

                                  {
        if ($this->exporter) {
            return mapi_exportchanges_synchronize($this->exporter);
        }
            return false;
    }

Member Data Documentation

Definition at line 61 of file exporter.php.

Definition at line 64 of file exporter.php.

Definition at line 63 of file exporter.php.

Definition at line 62 of file exporter.php.

Definition at line 57 of file exporter.php.

Definition at line 60 of file exporter.php.

Definition at line 59 of file exporter.php.

Definition at line 58 of file exporter.php.


The documentation for this class was generated from the following file: