Back to index

d-push  2.0
importchangesdiff.php
Go to the documentation of this file.
00001 <?php
00002 /***********************************************
00003 * File      :   importchangesdiff.php
00004 * Project   :   Z-Push
00005 * Descr     :   IImportChanges implementation using
00006 *               the differential engine
00007 *
00008 * Created   :   02.01.2012
00009 *
00010 * Copyright 2007 - 2012 Zarafa Deutschland GmbH
00011 *
00012 * This program is free software: you can redistribute it and/or modify
00013 * it under the terms of the GNU Affero General Public License, version 3,
00014 * as published by the Free Software Foundation with the following additional
00015 * term according to sec. 7:
00016 *
00017 * According to sec. 7 of the GNU Affero General Public License, version 3,
00018 * the terms of the AGPL are supplemented with the following terms:
00019 *
00020 * "Zarafa" is a registered trademark of Zarafa B.V.
00021 * "Z-Push" is a registered trademark of Zarafa Deutschland GmbH
00022 * The licensing of the Program under the AGPL does not imply a trademark license.
00023 * Therefore any rights, title and interest in our trademarks remain entirely with us.
00024 *
00025 * However, if you propagate an unmodified version of the Program you are
00026 * allowed to use the term "Z-Push" to indicate that you distribute the Program.
00027 * Furthermore you may use our trademarks where it is necessary to indicate
00028 * the intended purpose of a product or service provided you use it in accordance
00029 * with honest practices in industrial or commercial matters.
00030 * If you want to propagate modified versions of the Program under the name "Z-Push",
00031 * you may only do so if you have a written permission by Zarafa Deutschland GmbH
00032 * (to acquire a permission please contact Zarafa at trademark@zarafa.com).
00033 *
00034 * This program is distributed in the hope that it will be useful,
00035 * but WITHOUT ANY WARRANTY; without even the implied warranty of
00036 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00037 * GNU Affero General Public License for more details.
00038 *
00039 * You should have received a copy of the GNU Affero General Public License
00040 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
00041 *
00042 * Consult LICENSE file for details
00043 ************************************************/
00044 
00045 class ImportChangesDiff extends DiffState implements IImportChanges {
00046     private $folderid;
00047 
00057     public function ImportChangesDiff($backend, $folderid = false) {
00058         $this->backend = $backend;
00059         $this->folderid = $folderid;
00060     }
00061 
00073     public function LoadConflicts($contentparameters, $state) {
00074         // changes are detected on the fly
00075         return true;
00076     }
00077 
00088     public function ImportMessageChange($id, $message) {
00089         //do nothing if it is in a dummy folder
00090         if ($this->folderid == SYNC_FOLDER_TYPE_DUMMY)
00091             throw new StatusException(sprintf("ImportChangesDiff->ImportMessageChange('%s','%s'): can not be done on a dummy folder", $id, get_class($message)), SYNC_STATUS_SYNCCANNOTBECOMPLETED);
00092 
00093         if($id) {
00094             // See if there's a conflict
00095             $conflict = $this->isConflict("change", $this->folderid, $id);
00096 
00097             // Update client state if this is an update
00098             $change = array();
00099             $change["id"] = $id;
00100             $change["mod"] = 0; // dummy, will be updated later if the change succeeds
00101             $change["parent"] = $this->folderid;
00102             $change["flags"] = (isset($message->read)) ? $message->read : 0;
00103             $this->updateState("change", $change);
00104 
00105             if($conflict && $this->flags == SYNC_CONFLICT_OVERWRITE_PIM)
00106                 // in these cases the status SYNC_STATUS_CONFLICTCLIENTSERVEROBJECT should be returned, so the mobile client can inform the end user
00107                 throw new StatusException(sprintf("ImportChangesDiff->ImportMessageChange('%s','%s'): Conflict detected. Data from PIM will be dropped! Server overwrites PIM. User is informed.", $id, get_class($message)), SYNC_STATUS_CONFLICTCLIENTSERVEROBJECT, null, LOGLEVEL_INFO);
00108         }
00109 
00110         $stat = $this->backend->ChangeMessage($this->folderid, $id, $message);
00111 
00112         if(!is_array($stat))
00113             throw new StatusException(sprintf("ImportChangesDiff->ImportMessageChange('%s','%s'): unknown error in backend", $id, get_class($message)), SYNC_STATUS_SYNCCANNOTBECOMPLETED);
00114 
00115         // Record the state of the message
00116         $this->updateState("change", $stat);
00117 
00118         return $stat["id"];
00119     }
00120 
00131     public function ImportMessageDeletion($id) {
00132         //do nothing if it is in a dummy folder
00133         if ($this->folderid == SYNC_FOLDER_TYPE_DUMMY)
00134             throw new StatusException(sprintf("ImportChangesDiff->ImportMessageDeletion('%s'): can not be done on a dummy folder", $id), SYNC_STATUS_SYNCCANNOTBECOMPLETED);
00135 
00136         // See if there's a conflict
00137         $conflict = $this->isConflict("delete", $this->folderid, $id);
00138 
00139         // Update client state
00140         $change = array();
00141         $change["id"] = $id;
00142         $this->updateState("delete", $change);
00143 
00144         // If there is a conflict, and the server 'wins', then return without performing the change
00145         // this will cause the exporter to 'see' the overriding item as a change, and send it back to the PIM
00146         if($conflict && $this->flags == SYNC_CONFLICT_OVERWRITE_PIM) {
00147             ZLog::Write(LOGLEVEL_INFO, sprintf("ImportChangesDiff->ImportMessageDeletion('%s'): Conflict detected. Data from PIM will be dropped! Object was deleted.", $id));
00148             return false;
00149         }
00150 
00151         $stat = $this->backend->DeleteMessage($this->folderid, $id);
00152         if(!$stat)
00153             throw new StatusException(sprintf("ImportChangesDiff->ImportMessageDeletion('%s'): Unknown error in backend", $id), SYNC_STATUS_OBJECTNOTFOUND);
00154 
00155         return true;
00156     }
00157 
00169     public function ImportMessageReadFlag($id, $flags) {
00170         //do nothing if it is a dummy folder
00171         if ($this->folderid == SYNC_FOLDER_TYPE_DUMMY)
00172             throw new StatusException(sprintf("ImportChangesDiff->ImportMessageReadFlag('%s','%s'): can not be done on a dummy folder", $id, $flags), SYNC_STATUS_SYNCCANNOTBECOMPLETED);
00173 
00174         // Update client state
00175         $change = array();
00176         $change["id"] = $id;
00177         $change["flags"] = $flags;
00178         $this->updateState("flags", $change);
00179 
00180         $stat = $this->backend->SetReadFlag($this->folderid, $id, $flags);
00181         if (!$stat)
00182             throw new StatusException(sprintf("ImportChangesDiff->ImportMessageReadFlag('%s','%s'): Error, unable retrieve message from backend", $id, $flags), SYNC_STATUS_OBJECTNOTFOUND);
00183 
00184         return true;
00185     }
00186 
00197     public function ImportMessageMove($id, $newfolder) {
00198         // don't move messages from or to a dummy folder (GetHierarchy compatibility)
00199         if ($this->folderid == SYNC_FOLDER_TYPE_DUMMY || $newfolder == SYNC_FOLDER_TYPE_DUMMY)
00200             throw new StatusException(sprintf("ImportChangesDiff->ImportMessageMove('%s'): can not be done on a dummy folder", $id), SYNC_MOVEITEMSSTATUS_CANNOTMOVE);
00201 
00202         return $this->backend->MoveMessage($this->folderid, $id, $newfolder);
00203     }
00204 
00205 
00215     public function ImportFolderChange($folder) {
00216         $id = $folder->serverid;
00217         $parent = $folder->parentid;
00218         $displayname = $folder->displayname;
00219         $type = $folder->type;
00220 
00221         //do nothing if it is a dummy folder
00222         if ($parent == SYNC_FOLDER_TYPE_DUMMY)
00223             throw new StatusException(sprintf("ImportChangesDiff->ImportFolderChange('%s'): can not be done on a dummy folder", $id), SYNC_FSSTATUS_SERVERERROR);
00224 
00225         if($id) {
00226             $change = array();
00227             $change["id"] = $id;
00228             $change["mod"] = $displayname;
00229             $change["parent"] = $parent;
00230             $change["flags"] = 0;
00231             $this->updateState("change", $change);
00232         }
00233 
00234         $stat = $this->backend->ChangeFolder($parent, $id, $displayname, $type);
00235 
00236         if($stat)
00237             $this->updateState("change", $stat);
00238 
00239         return $stat["id"];
00240     }
00241 
00252     public function ImportFolderDeletion($id, $parent = false) {
00253         //do nothing if it is a dummy folder
00254         if ($parent == SYNC_FOLDER_TYPE_DUMMY)
00255             throw new StatusException(sprintf("ImportChangesDiff->ImportFolderDeletion('%s','%s'): can not be done on a dummy folder", $id, $parent), SYNC_FSSTATUS_SERVERERROR);
00256 
00257         // check the foldertype
00258         $folder = $this->backend->GetFolder($id);
00259         if (isset($folder->type) && Utils::IsSystemFolder($folder->type))
00260             throw new StatusException(sprintf("ImportChangesDiff->ImportFolderDeletion('%s','%s'): Error deleting system/default folder", $id, $parent), SYNC_FSSTATUS_SYSTEMFOLDER);
00261 
00262         $ret = $this->backend->DeleteFolder($id, $parent);
00263         if (!$ret)
00264             throw new StatusException(sprintf("ImportChangesDiff->ImportFolderDeletion('%s','%s'): can not be done on a dummy folder", $id, $parent), SYNC_FSSTATUS_FOLDERDOESNOTEXIST);
00265 
00266         $change = array();
00267         $change["id"] = $id;
00268 
00269         $this->updateState("delete", $change);
00270 
00271         return true;
00272     }
00273 }
00274 
00275 ?>