Back to index

d-push  2.0
folderchange.php
Go to the documentation of this file.
00001 <?php
00002 /***********************************************
00003 * File      :   folderchange.php
00004 * Project   :   Z-Push
00005 * Descr     :   Provides the FOLDERCREATE, FOLDERDELETE, FOLDERUPDATE command
00006 *
00007 * Created   :   16.02.2012
00008 *
00009 * Copyright 2007 - 2012 Zarafa Deutschland GmbH
00010 *
00011 * This program is free software: you can redistribute it and/or modify
00012 * it under the terms of the GNU Affero General Public License, version 3,
00013 * as published by the Free Software Foundation with the following additional
00014 * term according to sec. 7:
00015 *
00016 * According to sec. 7 of the GNU Affero General Public License, version 3,
00017 * the terms of the AGPL are supplemented with the following terms:
00018 *
00019 * "Zarafa" is a registered trademark of Zarafa B.V.
00020 * "Z-Push" is a registered trademark of Zarafa Deutschland GmbH
00021 * The licensing of the Program under the AGPL does not imply a trademark license.
00022 * Therefore any rights, title and interest in our trademarks remain entirely with us.
00023 *
00024 * However, if you propagate an unmodified version of the Program you are
00025 * allowed to use the term "Z-Push" to indicate that you distribute the Program.
00026 * Furthermore you may use our trademarks where it is necessary to indicate
00027 * the intended purpose of a product or service provided you use it in accordance
00028 * with honest practices in industrial or commercial matters.
00029 * If you want to propagate modified versions of the Program under the name "Z-Push",
00030 * you may only do so if you have a written permission by Zarafa Deutschland GmbH
00031 * (to acquire a permission please contact Zarafa at trademark@zarafa.com).
00032 *
00033 * This program is distributed in the hope that it will be useful,
00034 * but WITHOUT ANY WARRANTY; without even the implied warranty of
00035 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00036 * GNU Affero General Public License for more details.
00037 *
00038 * You should have received a copy of the GNU Affero General Public License
00039 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
00040 *
00041 * Consult LICENSE file for details
00042 ************************************************/
00043 
00044 class FolderChange extends RequestProcessor {
00045 
00055     public function Handle ($commandCode) {
00056         $el = self::$decoder->getElement();
00057 
00058         if($el[EN_TYPE] != EN_TYPE_STARTTAG)
00059             return false;
00060 
00061         $create = $update = $delete = false;
00062         if($el[EN_TAG] == SYNC_FOLDERHIERARCHY_FOLDERCREATE)
00063             $create = true;
00064         else if($el[EN_TAG] == SYNC_FOLDERHIERARCHY_FOLDERUPDATE)
00065             $update = true;
00066         else if($el[EN_TAG] == SYNC_FOLDERHIERARCHY_FOLDERDELETE)
00067             $delete = true;
00068 
00069         if(!$create && !$update && !$delete)
00070             return false;
00071 
00072         // SyncKey
00073         if(!self::$decoder->getElementStartTag(SYNC_FOLDERHIERARCHY_SYNCKEY))
00074             return false;
00075         $synckey = self::$decoder->getElementContent();
00076         if(!self::$decoder->getElementEndTag())
00077             return false;
00078 
00079         // ServerID
00080         $serverid = false;
00081         if(self::$decoder->getElementStartTag(SYNC_FOLDERHIERARCHY_SERVERENTRYID)) {
00082             $serverid = self::$decoder->getElementContent();
00083             if(!self::$decoder->getElementEndTag())
00084                 return false;
00085         }
00086 
00087         // Parent
00088         $parentid = false;
00089 
00090         // when creating or updating more information is necessary
00091         if (!$delete) {
00092             if(self::$decoder->getElementStartTag(SYNC_FOLDERHIERARCHY_PARENTID)) {
00093                 $parentid = self::$decoder->getElementContent();
00094                 if(!self::$decoder->getElementEndTag())
00095                     return false;
00096             }
00097 
00098             // Displayname
00099             if(!self::$decoder->getElementStartTag(SYNC_FOLDERHIERARCHY_DISPLAYNAME))
00100                 return false;
00101             $displayname = self::$decoder->getElementContent();
00102             if(!self::$decoder->getElementEndTag())
00103                 return false;
00104 
00105             // Type
00106             $type = false;
00107             if(self::$decoder->getElementStartTag(SYNC_FOLDERHIERARCHY_TYPE)) {
00108                 $type = self::$decoder->getElementContent();
00109                 if(!self::$decoder->getElementEndTag())
00110                     return false;
00111             }
00112         }
00113 
00114         if(!self::$decoder->getElementEndTag())
00115             return false;
00116 
00117         $status = SYNC_FSSTATUS_SUCCESS;
00118         // Get state of hierarchy
00119         try {
00120             $syncstate = self::$deviceManager->GetStateManager()->GetSyncState($synckey);
00121             $newsynckey = self::$deviceManager->GetStateManager()->GetNewSyncKey($synckey);
00122 
00123             // Over the ChangesWrapper the HierarchyCache is notified about all changes
00124             $changesMem = self::$deviceManager->GetHierarchyChangesWrapper();
00125 
00126             // the hierarchyCache should now fully be initialized - check for changes in the additional folders
00127             $changesMem->Config(ZPush::GetAdditionalSyncFolders());
00128 
00129             // there are unprocessed changes in the hierarchy, trigger resync
00130             if ($changesMem->GetChangeCount() > 0)
00131                 throw new StatusException("HandleFolderChange() can not proceed as there are unprocessed hierarchy changes", SYNC_FSSTATUS_SERVERERROR);
00132 
00133             // any additional folders can not be modified!
00134             if ($serverid !== false && ZPush::GetAdditionalSyncFolderStore($serverid))
00135                 throw new StatusException("HandleFolderChange() can not change additional folders which are configured", SYNC_FSSTATUS_UNKNOWNERROR);
00136 
00137             // switch user store if this this happens inside an additional folder
00138             // if this is an additional folder the backend has to be setup correctly
00139             if (!self::$backend->Setup(ZPush::GetAdditionalSyncFolderStore((($parentid != false)?$parentid:$serverid))))
00140                 throw new StatusException(sprintf("HandleFolderChange() could not Setup() the backend for folder id '%s'", (($parentid != false)?$parentid:$serverid)), SYNC_FSSTATUS_SERVERERROR);
00141         }
00142         catch (StateNotFoundException $snfex) {
00143             $status = SYNC_FSSTATUS_SYNCKEYERROR;
00144         }
00145         catch (StatusException $stex) {
00146            $status = $stex->getCode();
00147         }
00148 
00149         // set $newsynckey in case of an error
00150         if (!isset($newsynckey))
00151             $newsynckey = $synckey;
00152 
00153         if ($status == SYNC_FSSTATUS_SUCCESS) {
00154             try {
00155                 // Configure importer with last state
00156                 $importer = self::$backend->GetImporter();
00157                 $importer->Config($syncstate);
00158 
00159                 // the messages from the PIM will be forwarded to the real importer
00160                 $changesMem->SetDestinationImporter($importer);
00161 
00162                 // process incoming change
00163                 if (!$delete) {
00164                     // Send change
00165                     $folder = new SyncFolder();
00166                     $folder->serverid = $serverid;
00167                     $folder->parentid = $parentid;
00168                     $folder->displayname = $displayname;
00169                     $folder->type = $type;
00170 
00171                     $serverid = $changesMem->ImportFolderChange($folder);
00172                 }
00173                 else {
00174                     // delete folder
00175                     $changesMem->ImportFolderDeletion($serverid, 0);
00176                 }
00177             }
00178             catch (StatusException $stex) {
00179                 $status = $stex->getCode();
00180             }
00181         }
00182 
00183         self::$encoder->startWBXML();
00184         if ($create) {
00185 
00186             self::$encoder->startTag(SYNC_FOLDERHIERARCHY_FOLDERCREATE);
00187             {
00188                 {
00189                     self::$encoder->startTag(SYNC_FOLDERHIERARCHY_STATUS);
00190                     self::$encoder->content($status);
00191                     self::$encoder->endTag();
00192 
00193                     self::$encoder->startTag(SYNC_FOLDERHIERARCHY_SYNCKEY);
00194                     self::$encoder->content($newsynckey);
00195                     self::$encoder->endTag();
00196 
00197                     self::$encoder->startTag(SYNC_FOLDERHIERARCHY_SERVERENTRYID);
00198                     self::$encoder->content($serverid);
00199                     self::$encoder->endTag();
00200                 }
00201                 self::$encoder->endTag();
00202             }
00203             self::$encoder->endTag();
00204         }
00205 
00206         elseif ($update) {
00207             self::$encoder->startTag(SYNC_FOLDERHIERARCHY_FOLDERUPDATE);
00208             {
00209                 {
00210                     self::$encoder->startTag(SYNC_FOLDERHIERARCHY_STATUS);
00211                     self::$encoder->content($status);
00212                     self::$encoder->endTag();
00213 
00214                     self::$encoder->startTag(SYNC_FOLDERHIERARCHY_SYNCKEY);
00215                     self::$encoder->content($newsynckey);
00216                     self::$encoder->endTag();
00217                 }
00218                 self::$encoder->endTag();
00219             }
00220         }
00221 
00222         elseif ($delete) {
00223             self::$encoder->startTag(SYNC_FOLDERHIERARCHY_FOLDERDELETE);
00224             {
00225                 {
00226                     self::$encoder->startTag(SYNC_FOLDERHIERARCHY_STATUS);
00227                     self::$encoder->content($status);
00228                     self::$encoder->endTag();
00229 
00230                     self::$encoder->startTag(SYNC_FOLDERHIERARCHY_SYNCKEY);
00231                     self::$encoder->content($newsynckey);
00232                     self::$encoder->endTag();
00233                 }
00234                 self::$encoder->endTag();
00235             }
00236         }
00237 
00238         self::$encoder->endTag();
00239 
00240         self::$topCollector->AnnounceInformation(sprintf("Operation status %d", $status), true);
00241 
00242         // Save the sync state for the next time
00243         self::$deviceManager->GetStateManager()->SetSyncState($newsynckey, $importer->GetState());
00244 
00245         return true;
00246     }
00247 }
00248 ?>