1 /* 2 * ***** BEGIN LICENSE BLOCK ***** 3 * Zimbra Collaboration Suite Web Client 4 * Copyright (C) 2008, 2009, 2010, 2011, 2013, 2014, 2016 Synacor, Inc. 5 * 6 * The contents of this file are subject to the Common Public Attribution License Version 1.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at: https://www.zimbra.com/license 9 * The License is based on the Mozilla Public License Version 1.1 but Sections 14 and 15 10 * have been added to cover use of software over a computer network and provide for limited attribution 11 * for the Original Developer. In addition, Exhibit A has been modified to be consistent with Exhibit B. 12 * 13 * Software distributed under the License is distributed on an "AS IS" basis, 14 * WITHOUT WARRANTY OF ANY KIND, either express or implied. 15 * See the License for the specific language governing rights and limitations under the License. 16 * The Original Code is Zimbra Open Source Web Client. 17 * The Initial Developer of the Original Code is Zimbra, Inc. All rights to the Original Code were 18 * transferred by Zimbra, Inc. to Synacor, Inc. on September 14, 2015. 19 * 20 * All portions of the code are Copyright (C) 2008, 2009, 2010, 2011, 2013, 2014, 2016 Synacor, Inc. All Rights Reserved. 21 * ***** END LICENSE BLOCK ***** 22 */ 23 24 ZmMiniCalCache = function(calViewController) { 25 this._calViewController = calViewController; 26 this.clearCache(); 27 }; 28 29 ZmMiniCalCache.prototype.toString = 30 function() { 31 return "ZmMiniCalCache"; 32 }; 33 34 ZmMiniCalCache.prototype.clearCache = 35 function() { 36 this._miniCalData = {}; 37 }; 38 39 ZmMiniCalCache.prototype.updateCache = 40 function(params, data) { 41 var key = this._getCacheKey(params); 42 this._miniCalData[key] = data; 43 }; 44 45 ZmMiniCalCache.prototype._getCacheKey = 46 function(params) { 47 var sortedFolderIds = []; 48 sortedFolderIds = sortedFolderIds.concat(params.folderIds); 49 sortedFolderIds.sort(); 50 return (params.start + ":" + params.end + ":" + sortedFolderIds.join(":")); 51 }; 52 53 ZmMiniCalCache.prototype._getMiniCalData = 54 function(params) { 55 var cacheKey = this._getCacheKey(params); 56 var cachedData = this._miniCalData[cacheKey]; 57 if (cachedData) { 58 this.highlightMiniCal(cachedData); 59 if (params.callback) { 60 params.callback.run(cachedData); 61 return; 62 } 63 return cachedData; 64 } 65 66 var jsonObj = {GetMiniCalRequest:{_jsns:"urn:zimbraMail"}}; 67 var request = jsonObj.GetMiniCalRequest; 68 69 this._setSoapParams(request, params); 70 71 appCtxt.getAppController().sendRequest({ 72 jsonObj: jsonObj, 73 asyncMode: true, 74 offlineCache: true, 75 callback: (new AjxCallback(this, this._getMiniCalResponse, [params])), 76 errorCallback: (new AjxCallback(this, this._handleMiniCalResponseError, [params])), 77 offlineCallback: this._getMiniCalOfflineResponse.bind(this, params), 78 noBusyOverlay: params.noBusyOverlay, 79 accountName: (appCtxt.multiAccounts ? appCtxt.accountList.mainAccount.name : null) 80 }); 81 }; 82 83 ZmMiniCalCache.prototype.getCacheData = 84 function(params) { 85 var cacheKey = this._getCacheKey(params); 86 var cachedData = this._miniCalData[cacheKey]; 87 if (cachedData) { 88 return cachedData; 89 } 90 }; 91 92 ZmMiniCalCache.prototype._handleMiniCalResponseError = 93 function(params, result) { 94 var code = result ? result.code : null; 95 if (code == ZmCsfeException.ACCT_NO_SUCH_ACCOUNT || 96 code == ZmCsfeException.MAIL_NO_SUCH_MOUNTPOINT) 97 { 98 var data = (result && result.data) ? result.data : null; 99 var id = (data && data.itemId && (data.itemId.length>0)) ? data.itemId[0] : null; 100 if (id && appCtxt.getById(id) && this._faultHandler) { 101 var folder = appCtxt.getById(id); 102 folder.noSuchFolder = true; 103 this._faultHandler.run(folder); 104 return true; 105 } 106 } 107 108 //continue with callback operation 109 if(params.callback) { 110 params.callback.run([]); 111 } 112 113 return true; 114 }; 115 116 ZmMiniCalCache.prototype._setSoapParams = 117 function(request, params) { 118 request.s = params.start; 119 request.e = params.end; 120 request.tz = params.tz; 121 122 var folderNode = null; 123 if (params.folderIds && params.folderIds.length) { 124 request.folder = []; 125 for (var i = 0; i < params.folderIds.length; i++) { 126 request.folder.push({id:params.folderIds[i]}); 127 } 128 } 129 if(params.tz){ 130 request.tz = []; 131 var timezone = AjxTimezone.getRule(params.tz); 132 request.tz.push({id:params.tz,stdoff: timezone ? timezone.standard.offset : 0}); 133 } 134 135 }; 136 137 ZmMiniCalCache.prototype.setFaultHandler = 138 function(faultHandler) { 139 this._faultHandler = faultHandler; 140 }; 141 142 ZmMiniCalCache.prototype._getMiniCalResponse = 143 function(params, result) { 144 var data = []; 145 if (!result) { return data; } 146 147 var callback = params.callback; 148 var resp = result && result._data && result._data; 149 var miniCalResponse = resp.GetMiniCalResponse; 150 151 if (miniCalResponse && miniCalResponse.date) { 152 var dates = miniCalResponse.date; 153 if (dates) { 154 for (var i = 0; i < dates.length; i++) { 155 if (dates[i]._content) { 156 data.push(dates[i]._content); 157 } 158 } 159 } 160 this.highlightMiniCal(data); 161 } else { 162 // always reset hiliting if empty response returned 163 this.highlightMiniCal([]); 164 } 165 166 var errors = (miniCalResponse && miniCalResponse.error); 167 this.handleError(errors); 168 169 this.updateCache(params, data); 170 171 if (params.callback) { 172 params.callback.run(data); 173 return; 174 } 175 176 return data; 177 }; 178 179 ZmMiniCalCache.prototype._getMiniCalOfflineResponse = 180 function(params) { 181 182 var calMgr = appCtxt.getCalManager(); 183 var calViewController = calMgr && calMgr.getCalViewController(); 184 if (calViewController) { 185 var apptCache = calViewController.getApptCache(); 186 if (apptCache) { 187 var folderIds = calViewController.getMainAccountCheckedCalendarIds(); 188 var searchParams = { folderIds: folderIds, 189 start: params.start, 190 end: params.end 191 }; 192 var apptList = apptCache.setSearchParams(searchParams); 193 if (apptList) { 194 apptCache.processOfflineMiniCal(params, apptList); 195 } else { 196 apptCache.offlineSearchAppts(searchParams, params, null); 197 } 198 } 199 } 200 } 201 202 ZmMiniCalCache.prototype.processBatchResponse = 203 function(miniCalResponse, data) { 204 if (!miniCalResponse) { return; } 205 206 for (var i = 0; i < miniCalResponse.length; i++) { 207 var dates = (miniCalResponse[i] && miniCalResponse[i].date); 208 if (dates) { 209 for (var j = 0; j < dates.length; j++) { 210 if (dates[j]._content) { 211 data.push(dates[j]._content); 212 } 213 } 214 } 215 216 var errors = (miniCalResponse[i] && miniCalResponse[i].error); 217 this.handleError(errors); 218 } 219 }; 220 221 ZmMiniCalCache.prototype.handleError = 222 function(errors) { 223 if (errors && errors.length) { 224 for (var i = 0; i < errors.length; i++) { 225 if (errors[i].code == ZmCsfeException.MAIL_NO_SUCH_FOLDER || errors[i].code == ZmCsfeException.MAIL_NO_SUCH_MOUNTPOINT || errors[i].code == ZmCsfeException.ACCT_NO_SUCH_ACCOUNT || errors[i].code == ZmCsfeException.SVC_PERM_DENIED) { 226 var id = errors[i].id; 227 if (id && appCtxt.getById(id)) { 228 var folder = appCtxt.getById(id); 229 folder.noSuchFolder = true; 230 } 231 } 232 } 233 } 234 }; 235 236 ZmMiniCalCache.prototype.highlightMiniCal = 237 function(dateArr) { 238 var highlight = {}; 239 for (var i = 0; i < dateArr.length; i++) { 240 if (dateArr[i]) { 241 highlight[dateArr[i]] = AjxDateFormat.parse("yyyyMMdd", dateArr[i]); 242 } 243 } 244 if (this._calViewController && this._calViewController._miniCalendar) { 245 this._calViewController._miniCalendar.setHilite(highlight, true, true); 246 } 247 }; 248