File: Sync.php

package info (click to toggle)
horde3 3.1.3-4etch7
  • links: PTS
  • area: main
  • in suites: etch
  • size: 22,876 kB
  • ctags: 18,071
  • sloc: php: 75,151; xml: 2,979; sql: 1,069; makefile: 79; sh: 64
file content (154 lines) | stat: -rw-r--r-- 4,758 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
<?php

include_once 'SyncML/Command.php';
include_once 'SyncML/Command/SyncElement.php';

/**
 * $Horde: framework/SyncML/SyncML/Command/Sync.php,v 1.17.10.8 2006/01/11 18:39:28 selsky Exp $
 *
 * Copyright 2005-2006 Karsten Fourmont <karsten@horde.org>
 *
 * The command handler for the &gt;Sync&lt; command is the central
 * class to dispatch sync messages.
 *
 * During parsing of the received XML, the actual sync commands (Add,
 * Replace, Delete) from the client are stored in the _syncElements
 * attribute.  When the output method of SyncML_Command_Sync is
 * called, these elements are processed and the resulting status
 * messages created.
 *
 * Then the server modifications are sent back to the client by the
 * handleSync method which is called from within the output method.
 *
 * 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  Karsten Fourmont <karsten@horde.org>
 * @since   Horde 3.0
 * @package SyncML
 */
class SyncML_Command_Sync extends Syncml_Command
{
    /**
     * @var SyncML_Command_SyncElement
     */
    var $_currentSyncElement;

    /**
     * @var array
     */
    var $_syncElements = array();

    /**
     * contacts, calendar, tasks or notes
     *
     * @var string
     */
    var $_targetURI;

    /**
     * Creates a response to a sync command.
     * Currently that's the place where we also create
     * the &lt;sync&gt; with the server changes that
     * needs to be send to the client.
     */
    function output($currentCmdID, &$output)
    {
        $state =& $_SESSION['SyncML.state'];
        $sync =& $state->getSync($this->_targetURI);
        if (!is_object($sync)) {
            $GLOBALS['backend']->logMessage('No sync object found for URI = ' . $this->_targetURI,
                                            __FILE__, __LINE__, PEAR_LOG_ERR);
            // @TODO: create meaningful status code here.
        }

        // Here's where client modifications are processed:
        foreach ($this->_syncElements as $element) {
            foreach ($element->getItems() as $item) {
                $result = $sync->handleSyncItem($item);
            }
            $currentCmdID = $element->output($currentCmdID, $output);
        }

        /* Now send client changes to server: this will precede the
         * <sync> response: */
        $currentCmdID = $sync->createSyncOutput($currentCmdID, $output);

        $status = &new SyncML_Command_Status(RESPONSE_OK, 'Sync');
        $status->setCmdRef($this->_cmdID);

        if ($this->_targetURI != null) {
            $status->setTargetRef($this->_targetURI);
        }

        if ($this->_sourceURI != null) {
            $status->setSourceRef($this->_sourceURI);
        }

        return $status->output($currentCmdID, $output);
    }

    function getTargetURI()
    {
        return $this->_targetURI;
    }

    function startElement($uri, $element, $attrs)
    {
        parent::startElement($uri, $element, $attrs);

        switch (count($this->_Stack)) {
        case 2:
            if ($element == 'Replace' || $element == 'Add' || $element == 'Delete') {
                $this->_currentSyncElement = &new SyncML_Command_SyncElement($element);
            }
            break;
        }

        if (isset($this->_currentSyncElement)) {
            $this->_currentSyncElement->startElement($uri, $element, $attrs);
        }
    }

    function endElement($uri, $element)
    {
        if (isset($this->_currentSyncElement)) {
            $this->_currentSyncElement->endElement($uri, $element);
        }

        switch (count($this->_Stack)) {
        case 2:
            if ($element == 'Replace' || $element == 'Add' || $element == 'Delete') {
                $this->_syncElements[] = $this->_currentSyncElement;
                unset($this->_currentSyncElement);
            }
            break;

        case 3:
            if ($element = 'LocURI' && !isset($this->_currentSyncElement)) {
                if ($this->_Stack[1] == 'Source') {
                    $this->_sourceURI = trim($this->_chars);
                } elseif ($this->_Stack[1] == 'Target') {
                    $this->_targetURI = basename(preg_replace('/\?.*$/', '', trim($this->_chars)));
                }
            }
            break;
        }

        parent::endElement($uri, $element);
    }

    function characters($str)
    {
        if (isset($this->_currentSyncElement)) {
            $this->_currentSyncElement->characters($str);
        } else {
            if (isset($this->_chars)) {
                $this->_chars = $this->_chars . $str;
            } else {
                $this->_chars = $str;
            }
        }
    }

}