source: trunk/zpush/lib/request/folderchange.php @ 7589

Revision 7589, 9.7 KB checked in by douglas, 11 years ago (diff)

Ticket #3209 - Integrar módulo de sincronização Z-push ao Expresso

Line 
1<?php
2/***********************************************
3* File      :   folderchange.php
4* Project   :   Z-Push
5* Descr     :   Provides the FOLDERCREATE, FOLDERDELETE, FOLDERUPDATE command
6*
7* Created   :   16.02.2012
8*
9* Copyright 2007 - 2012 Zarafa Deutschland GmbH
10*
11* This program is free software: you can redistribute it and/or modify
12* it under the terms of the GNU Affero General Public License, version 3,
13* as published by the Free Software Foundation with the following additional
14* term according to sec. 7:
15*
16* According to sec. 7 of the GNU Affero General Public License, version 3,
17* the terms of the AGPL are supplemented with the following terms:
18*
19* "Zarafa" is a registered trademark of Zarafa B.V.
20* "Z-Push" is a registered trademark of Zarafa Deutschland GmbH
21* The licensing of the Program under the AGPL does not imply a trademark license.
22* Therefore any rights, title and interest in our trademarks remain entirely with us.
23*
24* However, if you propagate an unmodified version of the Program you are
25* allowed to use the term "Z-Push" to indicate that you distribute the Program.
26* Furthermore you may use our trademarks where it is necessary to indicate
27* the intended purpose of a product or service provided you use it in accordance
28* with honest practices in industrial or commercial matters.
29* If you want to propagate modified versions of the Program under the name "Z-Push",
30* you may only do so if you have a written permission by Zarafa Deutschland GmbH
31* (to acquire a permission please contact Zarafa at trademark@zarafa.com).
32*
33* This program is distributed in the hope that it will be useful,
34* but WITHOUT ANY WARRANTY; without even the implied warranty of
35* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
36* GNU Affero General Public License for more details.
37*
38* You should have received a copy of the GNU Affero General Public License
39* along with this program.  If not, see <http://www.gnu.org/licenses/>.
40*
41* Consult LICENSE file for details
42************************************************/
43
44class FolderChange extends RequestProcessor {
45
46    /**
47     * Handles creates, updates or deletes of a folder
48     * issued by the commands FolderCreate, FolderUpdate and FolderDelete
49     *
50     * @param int       $commandCode
51     *
52     * @access public
53     * @return boolean
54     */
55    public function Handle ($commandCode) {
56        $el = self::$decoder->getElement();
57
58        if($el[EN_TYPE] != EN_TYPE_STARTTAG)
59            return false;
60
61        $create = $update = $delete = false;
62        if($el[EN_TAG] == SYNC_FOLDERHIERARCHY_FOLDERCREATE)
63            $create = true;
64        else if($el[EN_TAG] == SYNC_FOLDERHIERARCHY_FOLDERUPDATE)
65            $update = true;
66        else if($el[EN_TAG] == SYNC_FOLDERHIERARCHY_FOLDERDELETE)
67            $delete = true;
68
69        if(!$create && !$update && !$delete)
70            return false;
71
72        // SyncKey
73        if(!self::$decoder->getElementStartTag(SYNC_FOLDERHIERARCHY_SYNCKEY))
74            return false;
75        $synckey = self::$decoder->getElementContent();
76        if(!self::$decoder->getElementEndTag())
77            return false;
78
79        // ServerID
80        $serverid = false;
81        if(self::$decoder->getElementStartTag(SYNC_FOLDERHIERARCHY_SERVERENTRYID)) {
82            $serverid = self::$decoder->getElementContent();
83            if(!self::$decoder->getElementEndTag())
84                return false;
85        }
86
87        // Parent
88        $parentid = false;
89
90        // when creating or updating more information is necessary
91        if (!$delete) {
92            if(self::$decoder->getElementStartTag(SYNC_FOLDERHIERARCHY_PARENTID)) {
93                $parentid = self::$decoder->getElementContent();
94                if(!self::$decoder->getElementEndTag())
95                    return false;
96            }
97
98            // Displayname
99            if(!self::$decoder->getElementStartTag(SYNC_FOLDERHIERARCHY_DISPLAYNAME))
100                return false;
101            $displayname = self::$decoder->getElementContent();
102            if(!self::$decoder->getElementEndTag())
103                return false;
104
105            // Type
106            $type = false;
107            if(self::$decoder->getElementStartTag(SYNC_FOLDERHIERARCHY_TYPE)) {
108                $type = self::$decoder->getElementContent();
109                if(!self::$decoder->getElementEndTag())
110                    return false;
111            }
112        }
113
114        if(!self::$decoder->getElementEndTag())
115            return false;
116
117        $status = SYNC_FSSTATUS_SUCCESS;
118        // Get state of hierarchy
119        try {
120            $syncstate = self::$deviceManager->GetStateManager()->GetSyncState($synckey);
121            $newsynckey = self::$deviceManager->GetStateManager()->GetNewSyncKey($synckey);
122
123            // Over the ChangesWrapper the HierarchyCache is notified about all changes
124            $changesMem = self::$deviceManager->GetHierarchyChangesWrapper();
125
126            // the hierarchyCache should now fully be initialized - check for changes in the additional folders
127            $changesMem->Config(ZPush::GetAdditionalSyncFolders());
128
129            // there are unprocessed changes in the hierarchy, trigger resync
130            if ($changesMem->GetChangeCount() > 0)
131                throw new StatusException("HandleFolderChange() can not proceed as there are unprocessed hierarchy changes", SYNC_FSSTATUS_SERVERERROR);
132
133            // any additional folders can not be modified!
134            if ($serverid !== false && ZPush::GetAdditionalSyncFolderStore($serverid))
135                throw new StatusException("HandleFolderChange() can not change additional folders which are configured", SYNC_FSSTATUS_SYSTEMFOLDER);
136
137            // switch user store if this this happens inside an additional folder
138            // if this is an additional folder the backend has to be setup correctly
139            if (!self::$backend->Setup(ZPush::GetAdditionalSyncFolderStore((($parentid != false)?$parentid:$serverid))))
140                throw new StatusException(sprintf("HandleFolderChange() could not Setup() the backend for folder id '%s'", (($parentid != false)?$parentid:$serverid)), SYNC_FSSTATUS_SERVERERROR);
141        }
142        catch (StateNotFoundException $snfex) {
143            $status = SYNC_FSSTATUS_SYNCKEYERROR;
144        }
145        catch (StatusException $stex) {
146           $status = $stex->getCode();
147        }
148
149        // set $newsynckey in case of an error
150        if (!isset($newsynckey))
151            $newsynckey = $synckey;
152
153        if ($status == SYNC_FSSTATUS_SUCCESS) {
154            try {
155                // Configure importer with last state
156                $importer = self::$backend->GetImporter();
157                $importer->Config($syncstate);
158
159                // the messages from the PIM will be forwarded to the real importer
160                $changesMem->SetDestinationImporter($importer);
161
162                // process incoming change
163                if (!$delete) {
164                    // Send change
165                    $folder = new SyncFolder();
166                    $folder->serverid = $serverid;
167                    $folder->parentid = $parentid;
168                    $folder->displayname = $displayname;
169                    $folder->type = $type;
170
171                    $serverid = $changesMem->ImportFolderChange($folder);
172                }
173                else {
174                    // delete folder
175                    $changesMem->ImportFolderDeletion($serverid, 0);
176                }
177            }
178            catch (StatusException $stex) {
179                $status = $stex->getCode();
180            }
181        }
182
183        self::$encoder->startWBXML();
184        if ($create) {
185
186            self::$encoder->startTag(SYNC_FOLDERHIERARCHY_FOLDERCREATE);
187            {
188                {
189                    self::$encoder->startTag(SYNC_FOLDERHIERARCHY_STATUS);
190                    self::$encoder->content($status);
191                    self::$encoder->endTag();
192
193                    self::$encoder->startTag(SYNC_FOLDERHIERARCHY_SYNCKEY);
194                    self::$encoder->content($newsynckey);
195                    self::$encoder->endTag();
196
197                    self::$encoder->startTag(SYNC_FOLDERHIERARCHY_SERVERENTRYID);
198                    self::$encoder->content($serverid);
199                    self::$encoder->endTag();
200                }
201                self::$encoder->endTag();
202            }
203            self::$encoder->endTag();
204        }
205
206        elseif ($update) {
207            self::$encoder->startTag(SYNC_FOLDERHIERARCHY_FOLDERUPDATE);
208            {
209                {
210                    self::$encoder->startTag(SYNC_FOLDERHIERARCHY_STATUS);
211                    self::$encoder->content($status);
212                    self::$encoder->endTag();
213
214                    self::$encoder->startTag(SYNC_FOLDERHIERARCHY_SYNCKEY);
215                    self::$encoder->content($newsynckey);
216                    self::$encoder->endTag();
217                }
218                self::$encoder->endTag();
219            }
220        }
221
222        elseif ($delete) {
223            self::$encoder->startTag(SYNC_FOLDERHIERARCHY_FOLDERDELETE);
224            {
225                {
226                    self::$encoder->startTag(SYNC_FOLDERHIERARCHY_STATUS);
227                    self::$encoder->content($status);
228                    self::$encoder->endTag();
229
230                    self::$encoder->startTag(SYNC_FOLDERHIERARCHY_SYNCKEY);
231                    self::$encoder->content($newsynckey);
232                    self::$encoder->endTag();
233                }
234                self::$encoder->endTag();
235            }
236        }
237
238        self::$encoder->endTag();
239
240        self::$topCollector->AnnounceInformation(sprintf("Operation status %d", $status), true);
241
242        // Save the sync state for the next time
243        if (isset($importer))
244            self::$deviceManager->GetStateManager()->SetSyncState($newsynckey, $importer->GetState());
245
246        return true;
247    }
248}
249?>
Note: See TracBrowser for help on using the repository browser.