Passed
Push — master ( 34e8da...f497d2 )
by
unknown
06:10 queued 02:50
created
lib/request/ping.php 2 patches
Indentation   +235 added lines, -235 removed lines patch added patch discarded remove patch
@@ -8,269 +8,269 @@
 block discarded – undo
8 8
  */
9 9
 
10 10
 class Ping extends RequestProcessor {
11
-	/**
12
-	 * Handles the Ping command.
13
-	 *
14
-	 * @param int $commandCode
15
-	 *
16
-	 * @return bool
17
-	 */
18
-	public function Handle($commandCode) {
19
-		$interval = (defined('PING_INTERVAL') && PING_INTERVAL > 0) ? PING_INTERVAL : 30;
20
-		$pingstatus = false;
21
-		$fakechanges = [];
22
-		$foundchanges = false;
11
+    /**
12
+     * Handles the Ping command.
13
+     *
14
+     * @param int $commandCode
15
+     *
16
+     * @return bool
17
+     */
18
+    public function Handle($commandCode) {
19
+        $interval = (defined('PING_INTERVAL') && PING_INTERVAL > 0) ? PING_INTERVAL : 30;
20
+        $pingstatus = false;
21
+        $fakechanges = [];
22
+        $foundchanges = false;
23 23
 
24
-		// Contains all requested folders (containers)
25
-		$sc = new SyncCollections();
24
+        // Contains all requested folders (containers)
25
+        $sc = new SyncCollections();
26 26
 
27
-		// read from stream to see if the symc params are being sent
28
-		$params_present = self::$decoder->getElementStartTag(SYNC_PING_PING);
27
+        // read from stream to see if the symc params are being sent
28
+        $params_present = self::$decoder->getElementStartTag(SYNC_PING_PING);
29 29
 
30
-		// Load all collections - do load states, check permissions and allow unconfirmed states
31
-		try {
32
-			$sc->LoadAllCollections(true, true, true, true, false);
33
-		}
34
-		catch (StateInvalidException $siex) {
35
-			// if no params are present, indicate to send params, else do hierarchy sync
36
-			if (!$params_present) {
37
-				$pingstatus = SYNC_PINGSTATUS_FAILINGPARAMS;
38
-				self::$topCollector->AnnounceInformation("StateInvalidException: require PingParameters", true);
39
-			}
40
-			elseif (self::$deviceManager->IsHierarchySyncRequired()) {
41
-				// we could be in a looping  - see LoopDetection->ProcessLoopDetectionIsHierarchySyncAdvised()
42
-				$pingstatus = SYNC_PINGSTATUS_FOLDERHIERSYNCREQUIRED;
43
-				self::$topCollector->AnnounceInformation("Potential loop detection: require HierarchySync", true);
44
-			}
45
-			else {
46
-				// we do not have a ping status for this, but SyncCollections should have generated fake changes for the folders which are broken
47
-				$fakechanges = $sc->GetChangedFolderIds();
48
-				$foundchanges = true;
30
+        // Load all collections - do load states, check permissions and allow unconfirmed states
31
+        try {
32
+            $sc->LoadAllCollections(true, true, true, true, false);
33
+        }
34
+        catch (StateInvalidException $siex) {
35
+            // if no params are present, indicate to send params, else do hierarchy sync
36
+            if (!$params_present) {
37
+                $pingstatus = SYNC_PINGSTATUS_FAILINGPARAMS;
38
+                self::$topCollector->AnnounceInformation("StateInvalidException: require PingParameters", true);
39
+            }
40
+            elseif (self::$deviceManager->IsHierarchySyncRequired()) {
41
+                // we could be in a looping  - see LoopDetection->ProcessLoopDetectionIsHierarchySyncAdvised()
42
+                $pingstatus = SYNC_PINGSTATUS_FOLDERHIERSYNCREQUIRED;
43
+                self::$topCollector->AnnounceInformation("Potential loop detection: require HierarchySync", true);
44
+            }
45
+            else {
46
+                // we do not have a ping status for this, but SyncCollections should have generated fake changes for the folders which are broken
47
+                $fakechanges = $sc->GetChangedFolderIds();
48
+                $foundchanges = true;
49 49
 
50
-				self::$topCollector->AnnounceInformation("StateInvalidException: force sync", true);
51
-			}
52
-		}
53
-		catch (StatusException $stex) {
54
-			$pingstatus = SYNC_PINGSTATUS_FOLDERHIERSYNCREQUIRED;
55
-			self::$topCollector->AnnounceInformation("StatusException: require HierarchySync", true);
56
-		}
50
+                self::$topCollector->AnnounceInformation("StateInvalidException: force sync", true);
51
+            }
52
+        }
53
+        catch (StatusException $stex) {
54
+            $pingstatus = SYNC_PINGSTATUS_FOLDERHIERSYNCREQUIRED;
55
+            self::$topCollector->AnnounceInformation("StatusException: require HierarchySync", true);
56
+        }
57 57
 
58
-		SLog::Write(LOGLEVEL_DEBUG, sprintf("HandlePing(): reference PolicyKey for PING: %s", $sc->GetReferencePolicyKey()));
58
+        SLog::Write(LOGLEVEL_DEBUG, sprintf("HandlePing(): reference PolicyKey for PING: %s", $sc->GetReferencePolicyKey()));
59 59
 
60
-		// receive PING initialization data
61
-		if ($params_present) {
62
-			self::$topCollector->AnnounceInformation("Processing PING data");
63
-			SLog::Write(LOGLEVEL_DEBUG, "HandlePing(): initialization data received");
60
+        // receive PING initialization data
61
+        if ($params_present) {
62
+            self::$topCollector->AnnounceInformation("Processing PING data");
63
+            SLog::Write(LOGLEVEL_DEBUG, "HandlePing(): initialization data received");
64 64
 
65
-			if (self::$decoder->getElementStartTag(SYNC_PING_LIFETIME)) {
66
-				$sc->SetLifetime(self::$decoder->getElementContent());
67
-				self::$decoder->getElementEndTag();
68
-			}
65
+            if (self::$decoder->getElementStartTag(SYNC_PING_LIFETIME)) {
66
+                $sc->SetLifetime(self::$decoder->getElementContent());
67
+                self::$decoder->getElementEndTag();
68
+            }
69 69
 
70
-			if (($el = self::$decoder->getElementStartTag(SYNC_PING_FOLDERS)) && $el[EN_FLAGS] & EN_FLAGS_CONTENT) {
71
-				// cache requested (pingable) folderids
72
-				$pingable = [];
70
+            if (($el = self::$decoder->getElementStartTag(SYNC_PING_FOLDERS)) && $el[EN_FLAGS] & EN_FLAGS_CONTENT) {
71
+                // cache requested (pingable) folderids
72
+                $pingable = [];
73 73
 
74
-				while (self::$decoder->getElementStartTag(SYNC_PING_FOLDER)) {
75
-					WBXMLDecoder::ResetInWhile("pingFolder");
76
-					while (WBXMLDecoder::InWhile("pingFolder")) {
77
-						if (self::$decoder->getElementStartTag(SYNC_PING_SERVERENTRYID)) {
78
-							$folderid = self::$decoder->getElementContent();
79
-							self::$decoder->getElementEndTag();
80
-						}
81
-						if (self::$decoder->getElementStartTag(SYNC_PING_FOLDERTYPE)) {
82
-							$class = self::$decoder->getElementContent();
83
-							self::$decoder->getElementEndTag();
84
-						}
74
+                while (self::$decoder->getElementStartTag(SYNC_PING_FOLDER)) {
75
+                    WBXMLDecoder::ResetInWhile("pingFolder");
76
+                    while (WBXMLDecoder::InWhile("pingFolder")) {
77
+                        if (self::$decoder->getElementStartTag(SYNC_PING_SERVERENTRYID)) {
78
+                            $folderid = self::$decoder->getElementContent();
79
+                            self::$decoder->getElementEndTag();
80
+                        }
81
+                        if (self::$decoder->getElementStartTag(SYNC_PING_FOLDERTYPE)) {
82
+                            $class = self::$decoder->getElementContent();
83
+                            self::$decoder->getElementEndTag();
84
+                        }
85 85
 
86
-						$e = self::$decoder->peek();
87
-						if ($e[EN_TYPE] == EN_TYPE_ENDTAG) {
88
-							self::$decoder->getElementEndTag();
86
+                        $e = self::$decoder->peek();
87
+                        if ($e[EN_TYPE] == EN_TYPE_ENDTAG) {
88
+                            self::$decoder->getElementEndTag();
89 89
 
90
-							break;
91
-						}
92
-					}
90
+                            break;
91
+                        }
92
+                    }
93 93
 
94
-					$spa = $sc->GetCollection($folderid);
95
-					if (!$spa) {
96
-						// The requested collection is not synchronized.
97
-						// check if the HierarchyCache is available, if not, trigger a HierarchySync
98
-						try {
99
-							self::$deviceManager->GetFolderClassFromCacheByID($folderid);
100
-							// ZP-907: ignore all folders with SYNC_FOLDER_TYPE_UNKNOWN
101
-							if (self::$deviceManager->GetFolderTypeFromCacheById($folderid) == SYNC_FOLDER_TYPE_UNKNOWN) {
102
-								SLog::Write(LOGLEVEL_DEBUG, sprintf("HandlePing(): ignoring folder id '%s' as it's of type UNKNOWN ", $folderid));
94
+                    $spa = $sc->GetCollection($folderid);
95
+                    if (!$spa) {
96
+                        // The requested collection is not synchronized.
97
+                        // check if the HierarchyCache is available, if not, trigger a HierarchySync
98
+                        try {
99
+                            self::$deviceManager->GetFolderClassFromCacheByID($folderid);
100
+                            // ZP-907: ignore all folders with SYNC_FOLDER_TYPE_UNKNOWN
101
+                            if (self::$deviceManager->GetFolderTypeFromCacheById($folderid) == SYNC_FOLDER_TYPE_UNKNOWN) {
102
+                                SLog::Write(LOGLEVEL_DEBUG, sprintf("HandlePing(): ignoring folder id '%s' as it's of type UNKNOWN ", $folderid));
103 103
 
104
-								continue;
105
-							}
106
-						}
107
-						catch (NoHierarchyCacheAvailableException $nhca) {
108
-							SLog::Write(LOGLEVEL_INFO, sprintf("HandlePing(): unknown collection '%s', triggering HierarchySync", $folderid));
109
-							$pingstatus = SYNC_PINGSTATUS_FOLDERHIERSYNCREQUIRED;
110
-						}
104
+                                continue;
105
+                            }
106
+                        }
107
+                        catch (NoHierarchyCacheAvailableException $nhca) {
108
+                            SLog::Write(LOGLEVEL_INFO, sprintf("HandlePing(): unknown collection '%s', triggering HierarchySync", $folderid));
109
+                            $pingstatus = SYNC_PINGSTATUS_FOLDERHIERSYNCREQUIRED;
110
+                        }
111 111
 
112
-						// Trigger a Sync request because then the device will be forced to resync this folder.
113
-						$fakechanges[$folderid] = 1;
114
-						$foundchanges = true;
115
-					}
116
-					elseif ($class == $spa->GetContentClass()) {
117
-						$pingable[] = $folderid;
118
-						SLog::Write(LOGLEVEL_DEBUG, sprintf("HandlePing(): using saved sync state for '%s' id '%s'", $spa->GetContentClass(), $folderid));
119
-					}
120
-				}
121
-				if (!self::$decoder->getElementEndTag()) {
122
-					return false;
123
-				}
112
+                        // Trigger a Sync request because then the device will be forced to resync this folder.
113
+                        $fakechanges[$folderid] = 1;
114
+                        $foundchanges = true;
115
+                    }
116
+                    elseif ($class == $spa->GetContentClass()) {
117
+                        $pingable[] = $folderid;
118
+                        SLog::Write(LOGLEVEL_DEBUG, sprintf("HandlePing(): using saved sync state for '%s' id '%s'", $spa->GetContentClass(), $folderid));
119
+                    }
120
+                }
121
+                if (!self::$decoder->getElementEndTag()) {
122
+                    return false;
123
+                }
124 124
 
125
-				// update pingable flags
126
-				foreach ($sc as $folderid => $spa) {
127
-					// if the folderid is in $pingable, we should ping it, else remove the flag
128
-					if (in_array($folderid, $pingable)) {
129
-						$spa->SetPingableFlag(true);
130
-					}
131
-					else {
132
-						$spa->DelPingableFlag();
133
-					}
134
-				}
135
-			}
136
-			if (!self::$decoder->getElementEndTag()) {
137
-				return false;
138
-			}
125
+                // update pingable flags
126
+                foreach ($sc as $folderid => $spa) {
127
+                    // if the folderid is in $pingable, we should ping it, else remove the flag
128
+                    if (in_array($folderid, $pingable)) {
129
+                        $spa->SetPingableFlag(true);
130
+                    }
131
+                    else {
132
+                        $spa->DelPingableFlag();
133
+                    }
134
+                }
135
+            }
136
+            if (!self::$decoder->getElementEndTag()) {
137
+                return false;
138
+            }
139 139
 
140
-			if (!$this->lifetimeBetweenBound($sc->GetLifetime())) {
141
-				$pingstatus = SYNC_PINGSTATUS_HBOUTOFRANGE;
142
-				SLog::Write(LOGLEVEL_DEBUG, sprintf("HandlePing(): ping lifetime not between bound (higher bound:'%d' lower bound:'%d' current lifetime:'%d'. Returning SYNC_PINGSTATUS_HBOUTOFRANGE.", PING_HIGHER_BOUND_LIFETIME, PING_LOWER_BOUND_LIFETIME, $sc->GetLifetime()));
143
-			}
144
-			// save changed data
145
-			foreach ($sc as $folderid => $spa) {
146
-				$sc->SaveCollection($spa);
147
-			}
148
-		} // END SYNC_PING_PING
149
-		else {
150
-			// if no ping initialization data was sent, we check if we have pingable folders
151
-			// if not, we indicate that there is nothing to do.
152
-			if (!$sc->PingableFolders()) {
153
-				$pingstatus = SYNC_PINGSTATUS_FAILINGPARAMS;
154
-				SLog::Write(LOGLEVEL_DEBUG, "HandlePing(): no pingable folders found and no initialization data sent. Returning SYNC_PINGSTATUS_FAILINGPARAMS.");
155
-			}
156
-			elseif (!$this->lifetimeBetweenBound($sc->GetLifetime())) {
157
-				$pingstatus = SYNC_PINGSTATUS_FAILINGPARAMS;
158
-				SLog::Write(LOGLEVEL_DEBUG, sprintf("HandlePing(): ping lifetime not between bound (higher bound:'%d' lower bound:'%d' current lifetime:'%d'. Returning SYNC_PINGSTATUS_FAILINGPARAMS.", PING_HIGHER_BOUND_LIFETIME, PING_LOWER_BOUND_LIFETIME, $sc->GetLifetime()));
159
-			}
160
-		}
140
+            if (!$this->lifetimeBetweenBound($sc->GetLifetime())) {
141
+                $pingstatus = SYNC_PINGSTATUS_HBOUTOFRANGE;
142
+                SLog::Write(LOGLEVEL_DEBUG, sprintf("HandlePing(): ping lifetime not between bound (higher bound:'%d' lower bound:'%d' current lifetime:'%d'. Returning SYNC_PINGSTATUS_HBOUTOFRANGE.", PING_HIGHER_BOUND_LIFETIME, PING_LOWER_BOUND_LIFETIME, $sc->GetLifetime()));
143
+            }
144
+            // save changed data
145
+            foreach ($sc as $folderid => $spa) {
146
+                $sc->SaveCollection($spa);
147
+            }
148
+        } // END SYNC_PING_PING
149
+        else {
150
+            // if no ping initialization data was sent, we check if we have pingable folders
151
+            // if not, we indicate that there is nothing to do.
152
+            if (!$sc->PingableFolders()) {
153
+                $pingstatus = SYNC_PINGSTATUS_FAILINGPARAMS;
154
+                SLog::Write(LOGLEVEL_DEBUG, "HandlePing(): no pingable folders found and no initialization data sent. Returning SYNC_PINGSTATUS_FAILINGPARAMS.");
155
+            }
156
+            elseif (!$this->lifetimeBetweenBound($sc->GetLifetime())) {
157
+                $pingstatus = SYNC_PINGSTATUS_FAILINGPARAMS;
158
+                SLog::Write(LOGLEVEL_DEBUG, sprintf("HandlePing(): ping lifetime not between bound (higher bound:'%d' lower bound:'%d' current lifetime:'%d'. Returning SYNC_PINGSTATUS_FAILINGPARAMS.", PING_HIGHER_BOUND_LIFETIME, PING_LOWER_BOUND_LIFETIME, $sc->GetLifetime()));
159
+            }
160
+        }
161 161
 
162
-		// Check for changes on the default LifeTime, set interval and ONLY on pingable collections
163
-		try {
164
-			if (!$pingstatus && empty($fakechanges)) {
165
-				self::$deviceManager->DoAutomaticASDeviceSaving(false);
166
-				$foundchanges = $sc->CheckForChanges($sc->GetLifetime(), $interval, true);
167
-			}
168
-		}
169
-		catch (StatusException $ste) {
170
-			switch ($ste->getCode()) {
171
-				case SyncCollections::ERROR_NO_COLLECTIONS:
172
-					$pingstatus = SYNC_PINGSTATUS_FAILINGPARAMS;
173
-					break;
162
+        // Check for changes on the default LifeTime, set interval and ONLY on pingable collections
163
+        try {
164
+            if (!$pingstatus && empty($fakechanges)) {
165
+                self::$deviceManager->DoAutomaticASDeviceSaving(false);
166
+                $foundchanges = $sc->CheckForChanges($sc->GetLifetime(), $interval, true);
167
+            }
168
+        }
169
+        catch (StatusException $ste) {
170
+            switch ($ste->getCode()) {
171
+                case SyncCollections::ERROR_NO_COLLECTIONS:
172
+                    $pingstatus = SYNC_PINGSTATUS_FAILINGPARAMS;
173
+                    break;
174 174
 
175
-				case SyncCollections::ERROR_WRONG_HIERARCHY:
176
-					$pingstatus = SYNC_PINGSTATUS_FOLDERHIERSYNCREQUIRED;
177
-					self::$deviceManager->AnnounceProcessStatus(false, $pingstatus);
178
-					break;
175
+                case SyncCollections::ERROR_WRONG_HIERARCHY:
176
+                    $pingstatus = SYNC_PINGSTATUS_FOLDERHIERSYNCREQUIRED;
177
+                    self::$deviceManager->AnnounceProcessStatus(false, $pingstatus);
178
+                    break;
179 179
 
180
-				case SyncCollections::OBSOLETE_CONNECTION:
181
-					$foundchanges = false;
182
-					break;
180
+                case SyncCollections::OBSOLETE_CONNECTION:
181
+                    $foundchanges = false;
182
+                    break;
183 183
 
184
-				case SyncCollections::HIERARCHY_CHANGED:
185
-					$pingstatus = SYNC_PINGSTATUS_FOLDERHIERSYNCREQUIRED;
186
-					break;
187
-			}
188
-		}
184
+                case SyncCollections::HIERARCHY_CHANGED:
185
+                    $pingstatus = SYNC_PINGSTATUS_FOLDERHIERSYNCREQUIRED;
186
+                    break;
187
+            }
188
+        }
189 189
 
190
-		self::$encoder->StartWBXML();
191
-		self::$encoder->startTag(SYNC_PING_PING);
190
+        self::$encoder->StartWBXML();
191
+        self::$encoder->startTag(SYNC_PING_PING);
192 192
 
193
-		self::$encoder->startTag(SYNC_PING_STATUS);
194
-		if (isset($pingstatus) && $pingstatus) {
195
-			self::$encoder->content($pingstatus);
196
-		}
197
-		else {
198
-			self::$encoder->content($foundchanges ? SYNC_PINGSTATUS_CHANGES : SYNC_PINGSTATUS_HBEXPIRED);
199
-		}
200
-		self::$encoder->endTag();
193
+        self::$encoder->startTag(SYNC_PING_STATUS);
194
+        if (isset($pingstatus) && $pingstatus) {
195
+            self::$encoder->content($pingstatus);
196
+        }
197
+        else {
198
+            self::$encoder->content($foundchanges ? SYNC_PINGSTATUS_CHANGES : SYNC_PINGSTATUS_HBEXPIRED);
199
+        }
200
+        self::$encoder->endTag();
201 201
 
202
-		if (!$pingstatus) {
203
-			self::$encoder->startTag(SYNC_PING_FOLDERS);
202
+        if (!$pingstatus) {
203
+            self::$encoder->startTag(SYNC_PING_FOLDERS);
204 204
 
205
-			if (empty($fakechanges)) {
206
-				$changes = $sc->GetChangedFolderIds();
207
-			}
208
-			else {
209
-				$changes = $fakechanges;
210
-			}
205
+            if (empty($fakechanges)) {
206
+                $changes = $sc->GetChangedFolderIds();
207
+            }
208
+            else {
209
+                $changes = $fakechanges;
210
+            }
211 211
 
212
-			$announceAggregated = false;
213
-			if (count($changes) > 1) {
214
-				$announceAggregated = 0;
215
-			}
216
-			foreach ($changes as $folderid => $changecount) {
217
-				if ($changecount > 0) {
218
-					self::$encoder->startTag(SYNC_PING_FOLDER);
219
-					self::$encoder->content($folderid);
220
-					self::$encoder->endTag();
221
-					if ($announceAggregated === false) {
222
-						if (empty($fakechanges)) {
223
-							self::$topCollector->AnnounceInformation(sprintf("Found change in %s", $sc->GetCollection($folderid)->GetContentClass()), true);
224
-						}
225
-					}
226
-					else {
227
-						$announceAggregated += $changecount;
228
-					}
229
-					self::$deviceManager->AnnounceProcessStatus($folderid, SYNC_PINGSTATUS_CHANGES);
230
-				}
231
-			}
232
-			if ($announceAggregated !== false) {
233
-				self::$topCollector->AnnounceInformation(sprintf("Found %d changes in %d folders", $announceAggregated, count($changes)), true);
234
-			}
235
-			self::$encoder->endTag();
236
-		}
237
-		elseif ($pingstatus == SYNC_PINGSTATUS_HBOUTOFRANGE) {
238
-			self::$encoder->startTag(SYNC_PING_LIFETIME);
239
-			if ($sc->GetLifetime() > PING_HIGHER_BOUND_LIFETIME) {
240
-				self::$encoder->content(PING_HIGHER_BOUND_LIFETIME);
241
-			}
242
-			else {
243
-				self::$encoder->content(PING_LOWER_BOUND_LIFETIME);
244
-			}
245
-			self::$encoder->endTag();
246
-		}
212
+            $announceAggregated = false;
213
+            if (count($changes) > 1) {
214
+                $announceAggregated = 0;
215
+            }
216
+            foreach ($changes as $folderid => $changecount) {
217
+                if ($changecount > 0) {
218
+                    self::$encoder->startTag(SYNC_PING_FOLDER);
219
+                    self::$encoder->content($folderid);
220
+                    self::$encoder->endTag();
221
+                    if ($announceAggregated === false) {
222
+                        if (empty($fakechanges)) {
223
+                            self::$topCollector->AnnounceInformation(sprintf("Found change in %s", $sc->GetCollection($folderid)->GetContentClass()), true);
224
+                        }
225
+                    }
226
+                    else {
227
+                        $announceAggregated += $changecount;
228
+                    }
229
+                    self::$deviceManager->AnnounceProcessStatus($folderid, SYNC_PINGSTATUS_CHANGES);
230
+                }
231
+            }
232
+            if ($announceAggregated !== false) {
233
+                self::$topCollector->AnnounceInformation(sprintf("Found %d changes in %d folders", $announceAggregated, count($changes)), true);
234
+            }
235
+            self::$encoder->endTag();
236
+        }
237
+        elseif ($pingstatus == SYNC_PINGSTATUS_HBOUTOFRANGE) {
238
+            self::$encoder->startTag(SYNC_PING_LIFETIME);
239
+            if ($sc->GetLifetime() > PING_HIGHER_BOUND_LIFETIME) {
240
+                self::$encoder->content(PING_HIGHER_BOUND_LIFETIME);
241
+            }
242
+            else {
243
+                self::$encoder->content(PING_LOWER_BOUND_LIFETIME);
244
+            }
245
+            self::$encoder->endTag();
246
+        }
247 247
 
248
-		self::$encoder->endTag();
248
+        self::$encoder->endTag();
249 249
 
250
-		// update the waittime waited
251
-		self::$waitTime = $sc->GetWaitedSeconds();
250
+        // update the waittime waited
251
+        self::$waitTime = $sc->GetWaitedSeconds();
252 252
 
253
-		return true;
254
-	}
253
+        return true;
254
+    }
255 255
 
256
-	/**
257
-	 * Return true if the ping lifetime is between the specified bound (PING_HIGHER_BOUND_LIFETIME and PING_LOWER_BOUND_LIFETIME). If no bound are specified, it returns true.
258
-	 *
259
-	 * @param int $lifetime
260
-	 *
261
-	 * @return bool
262
-	 */
263
-	private function lifetimeBetweenBound($lifetime) {
264
-		if (PING_HIGHER_BOUND_LIFETIME !== false && PING_LOWER_BOUND_LIFETIME !== false) {
265
-			return $lifetime <= PING_HIGHER_BOUND_LIFETIME && $lifetime >= PING_LOWER_BOUND_LIFETIME;
266
-		}
267
-		if (PING_HIGHER_BOUND_LIFETIME !== false) {
268
-			return $lifetime <= PING_HIGHER_BOUND_LIFETIME;
269
-		}
270
-		if (PING_LOWER_BOUND_LIFETIME !== false) {
271
-			return $lifetime >= PING_LOWER_BOUND_LIFETIME;
272
-		}
256
+    /**
257
+     * Return true if the ping lifetime is between the specified bound (PING_HIGHER_BOUND_LIFETIME and PING_LOWER_BOUND_LIFETIME). If no bound are specified, it returns true.
258
+     *
259
+     * @param int $lifetime
260
+     *
261
+     * @return bool
262
+     */
263
+    private function lifetimeBetweenBound($lifetime) {
264
+        if (PING_HIGHER_BOUND_LIFETIME !== false && PING_LOWER_BOUND_LIFETIME !== false) {
265
+            return $lifetime <= PING_HIGHER_BOUND_LIFETIME && $lifetime >= PING_LOWER_BOUND_LIFETIME;
266
+        }
267
+        if (PING_HIGHER_BOUND_LIFETIME !== false) {
268
+            return $lifetime <= PING_HIGHER_BOUND_LIFETIME;
269
+        }
270
+        if (PING_LOWER_BOUND_LIFETIME !== false) {
271
+            return $lifetime >= PING_LOWER_BOUND_LIFETIME;
272
+        }
273 273
 
274
-		return true;
275
-	}
274
+        return true;
275
+    }
276 276
 }
Please login to merge, or discard this patch.
Braces   +14 added lines, -28 removed lines patch added patch discarded remove patch
@@ -30,27 +30,23 @@  discard block
 block discarded – undo
30 30
 		// Load all collections - do load states, check permissions and allow unconfirmed states
31 31
 		try {
32 32
 			$sc->LoadAllCollections(true, true, true, true, false);
33
-		}
34
-		catch (StateInvalidException $siex) {
33
+		} catch (StateInvalidException $siex) {
35 34
 			// if no params are present, indicate to send params, else do hierarchy sync
36 35
 			if (!$params_present) {
37 36
 				$pingstatus = SYNC_PINGSTATUS_FAILINGPARAMS;
38 37
 				self::$topCollector->AnnounceInformation("StateInvalidException: require PingParameters", true);
39
-			}
40
-			elseif (self::$deviceManager->IsHierarchySyncRequired()) {
38
+			} elseif (self::$deviceManager->IsHierarchySyncRequired()) {
41 39
 				// we could be in a looping  - see LoopDetection->ProcessLoopDetectionIsHierarchySyncAdvised()
42 40
 				$pingstatus = SYNC_PINGSTATUS_FOLDERHIERSYNCREQUIRED;
43 41
 				self::$topCollector->AnnounceInformation("Potential loop detection: require HierarchySync", true);
44
-			}
45
-			else {
42
+			} else {
46 43
 				// we do not have a ping status for this, but SyncCollections should have generated fake changes for the folders which are broken
47 44
 				$fakechanges = $sc->GetChangedFolderIds();
48 45
 				$foundchanges = true;
49 46
 
50 47
 				self::$topCollector->AnnounceInformation("StateInvalidException: force sync", true);
51 48
 			}
52
-		}
53
-		catch (StatusException $stex) {
49
+		} catch (StatusException $stex) {
54 50
 			$pingstatus = SYNC_PINGSTATUS_FOLDERHIERSYNCREQUIRED;
55 51
 			self::$topCollector->AnnounceInformation("StatusException: require HierarchySync", true);
56 52
 		}
@@ -103,8 +99,7 @@  discard block
 block discarded – undo
103 99
 
104 100
 								continue;
105 101
 							}
106
-						}
107
-						catch (NoHierarchyCacheAvailableException $nhca) {
102
+						} catch (NoHierarchyCacheAvailableException $nhca) {
108 103
 							SLog::Write(LOGLEVEL_INFO, sprintf("HandlePing(): unknown collection '%s', triggering HierarchySync", $folderid));
109 104
 							$pingstatus = SYNC_PINGSTATUS_FOLDERHIERSYNCREQUIRED;
110 105
 						}
@@ -112,8 +107,7 @@  discard block
 block discarded – undo
112 107
 						// Trigger a Sync request because then the device will be forced to resync this folder.
113 108
 						$fakechanges[$folderid] = 1;
114 109
 						$foundchanges = true;
115
-					}
116
-					elseif ($class == $spa->GetContentClass()) {
110
+					} elseif ($class == $spa->GetContentClass()) {
117 111
 						$pingable[] = $folderid;
118 112
 						SLog::Write(LOGLEVEL_DEBUG, sprintf("HandlePing(): using saved sync state for '%s' id '%s'", $spa->GetContentClass(), $folderid));
119 113
 					}
@@ -127,8 +121,7 @@  discard block
 block discarded – undo
127 121
 					// if the folderid is in $pingable, we should ping it, else remove the flag
128 122
 					if (in_array($folderid, $pingable)) {
129 123
 						$spa->SetPingableFlag(true);
130
-					}
131
-					else {
124
+					} else {
132 125
 						$spa->DelPingableFlag();
133 126
 					}
134 127
 				}
@@ -152,8 +145,7 @@  discard block
 block discarded – undo
152 145
 			if (!$sc->PingableFolders()) {
153 146
 				$pingstatus = SYNC_PINGSTATUS_FAILINGPARAMS;
154 147
 				SLog::Write(LOGLEVEL_DEBUG, "HandlePing(): no pingable folders found and no initialization data sent. Returning SYNC_PINGSTATUS_FAILINGPARAMS.");
155
-			}
156
-			elseif (!$this->lifetimeBetweenBound($sc->GetLifetime())) {
148
+			} elseif (!$this->lifetimeBetweenBound($sc->GetLifetime())) {
157 149
 				$pingstatus = SYNC_PINGSTATUS_FAILINGPARAMS;
158 150
 				SLog::Write(LOGLEVEL_DEBUG, sprintf("HandlePing(): ping lifetime not between bound (higher bound:'%d' lower bound:'%d' current lifetime:'%d'. Returning SYNC_PINGSTATUS_FAILINGPARAMS.", PING_HIGHER_BOUND_LIFETIME, PING_LOWER_BOUND_LIFETIME, $sc->GetLifetime()));
159 151
 			}
@@ -165,8 +157,7 @@  discard block
 block discarded – undo
165 157
 				self::$deviceManager->DoAutomaticASDeviceSaving(false);
166 158
 				$foundchanges = $sc->CheckForChanges($sc->GetLifetime(), $interval, true);
167 159
 			}
168
-		}
169
-		catch (StatusException $ste) {
160
+		} catch (StatusException $ste) {
170 161
 			switch ($ste->getCode()) {
171 162
 				case SyncCollections::ERROR_NO_COLLECTIONS:
172 163
 					$pingstatus = SYNC_PINGSTATUS_FAILINGPARAMS;
@@ -193,8 +184,7 @@  discard block
 block discarded – undo
193 184
 		self::$encoder->startTag(SYNC_PING_STATUS);
194 185
 		if (isset($pingstatus) && $pingstatus) {
195 186
 			self::$encoder->content($pingstatus);
196
-		}
197
-		else {
187
+		} else {
198 188
 			self::$encoder->content($foundchanges ? SYNC_PINGSTATUS_CHANGES : SYNC_PINGSTATUS_HBEXPIRED);
199 189
 		}
200 190
 		self::$encoder->endTag();
@@ -204,8 +194,7 @@  discard block
 block discarded – undo
204 194
 
205 195
 			if (empty($fakechanges)) {
206 196
 				$changes = $sc->GetChangedFolderIds();
207
-			}
208
-			else {
197
+			} else {
209 198
 				$changes = $fakechanges;
210 199
 			}
211 200
 
@@ -222,8 +211,7 @@  discard block
 block discarded – undo
222 211
 						if (empty($fakechanges)) {
223 212
 							self::$topCollector->AnnounceInformation(sprintf("Found change in %s", $sc->GetCollection($folderid)->GetContentClass()), true);
224 213
 						}
225
-					}
226
-					else {
214
+					} else {
227 215
 						$announceAggregated += $changecount;
228 216
 					}
229 217
 					self::$deviceManager->AnnounceProcessStatus($folderid, SYNC_PINGSTATUS_CHANGES);
@@ -233,13 +221,11 @@  discard block
 block discarded – undo
233 221
 				self::$topCollector->AnnounceInformation(sprintf("Found %d changes in %d folders", $announceAggregated, count($changes)), true);
234 222
 			}
235 223
 			self::$encoder->endTag();
236
-		}
237
-		elseif ($pingstatus == SYNC_PINGSTATUS_HBOUTOFRANGE) {
224
+		} elseif ($pingstatus == SYNC_PINGSTATUS_HBOUTOFRANGE) {
238 225
 			self::$encoder->startTag(SYNC_PING_LIFETIME);
239 226
 			if ($sc->GetLifetime() > PING_HIGHER_BOUND_LIFETIME) {
240 227
 				self::$encoder->content(PING_HIGHER_BOUND_LIFETIME);
241
-			}
242
-			else {
228
+			} else {
243 229
 				self::$encoder->content(PING_LOWER_BOUND_LIFETIME);
244 230
 			}
245 231
 			self::$encoder->endTag();
Please login to merge, or discard this patch.
lib/request/itemoperations.php 3 patches
Indentation   +424 added lines, -424 removed lines patch added patch discarded remove patch
@@ -8,428 +8,428 @@
 block discarded – undo
8 8
  */
9 9
 
10 10
 class ItemOperations extends RequestProcessor {
11
-	/**
12
-	 * Handles the ItemOperations command
13
-	 * Provides batched online handling for Fetch, EmptyFolderContents and Move.
14
-	 *
15
-	 * @param int $commandCode
16
-	 *
17
-	 * @return bool
18
-	 */
19
-	public function Handle($commandCode) {
20
-		// Parse input
21
-		if (!self::$decoder->getElementStartTag(SYNC_ITEMOPERATIONS_ITEMOPERATIONS)) {
22
-			return false;
23
-		}
24
-
25
-		$itemoperations = [];
26
-		// ItemOperations can either be Fetch, EmptyFolderContents or Move
27
-		WBXMLDecoder::ResetInWhile("itemOperationsActions");
28
-		while (WBXMLDecoder::InWhile("itemOperationsActions")) {
29
-			// TODO check if multiple item operations are possible in one request
30
-			$el = self::$decoder->getElement();
31
-
32
-			if ($el[EN_TYPE] != EN_TYPE_STARTTAG) {
33
-				return false;
34
-			}
35
-
36
-			$fetch = $efc = $move = false;
37
-			$operation = [];
38
-			if ($el[EN_TAG] == SYNC_ITEMOPERATIONS_FETCH) {
39
-				$fetch = true;
40
-				$operation['operation'] = SYNC_ITEMOPERATIONS_FETCH;
41
-				self::$topCollector->AnnounceInformation("Fetch", true);
42
-			}
43
-			elseif ($el[EN_TAG] == SYNC_ITEMOPERATIONS_EMPTYFOLDERCONTENTS) {
44
-				$efc = true;
45
-				$operation['operation'] = SYNC_ITEMOPERATIONS_EMPTYFOLDERCONTENTS;
46
-				self::$topCollector->AnnounceInformation("Empty Folder", true);
47
-			}
48
-			elseif ($el[EN_TAG] == SYNC_ITEMOPERATIONS_MOVE) {
49
-				$move = true;
50
-				$operation['operation'] = SYNC_ITEMOPERATIONS_MOVE;
51
-				self::$topCollector->AnnounceInformation("Move", true);
52
-			}
53
-
54
-			if (!$fetch && !$efc && !$move) {
55
-				SLog::Write(LOGLEVEL_DEBUG, "Unknown item operation:" . print_r($el, 1));
56
-				self::$topCollector->AnnounceInformation("Unknown operation", true);
57
-
58
-				return false;
59
-			}
60
-
61
-			// process operation
62
-			WBXMLDecoder::ResetInWhile("itemOperationsOperation");
63
-			while (WBXMLDecoder::InWhile("itemOperationsOperation")) {
64
-				if ($fetch) {
65
-					// Save all OPTIONS into a ContentParameters object
66
-					$operation["cpo"] = new ContentParameters();
67
-
68
-					if (self::$decoder->getElementStartTag(SYNC_ITEMOPERATIONS_STORE)) {
69
-						$operation['store'] = self::$decoder->getElementContent();
70
-						if (!self::$decoder->getElementEndTag()) {
71
-							return false;
72
-						}// SYNC_ITEMOPERATIONS_STORE
73
-					}
74
-
75
-					if (self::$decoder->getElementStartTag(SYNC_SEARCH_LONGID)) {
76
-						$operation['longid'] = self::$decoder->getElementContent();
77
-						if (!self::$decoder->getElementEndTag()) {
78
-							return false;
79
-						}// SYNC_SEARCH_LONGID
80
-					}
81
-
82
-					if (self::$decoder->getElementStartTag(SYNC_FOLDERID)) {
83
-						$operation['folderid'] = self::$decoder->getElementContent();
84
-						if (!self::$decoder->getElementEndTag()) {
85
-							return false;
86
-						}// SYNC_FOLDERID
87
-					}
88
-
89
-					if (self::$decoder->getElementStartTag(SYNC_SERVERENTRYID)) {
90
-						$operation['serverid'] = self::$decoder->getElementContent();
91
-						if (!self::$decoder->getElementEndTag()) {
92
-							return false;
93
-						}// SYNC_SERVERENTRYID
94
-					}
95
-
96
-					if (self::$decoder->getElementStartTag(SYNC_AIRSYNCBASE_FILEREFERENCE)) {
97
-						$operation['filereference'] = self::$decoder->getElementContent();
98
-						if (!self::$decoder->getElementEndTag()) {
99
-							return false;
100
-						}// SYNC_AIRSYNCBASE_FILEREFERENCE
101
-					}
102
-
103
-					if (($el = self::$decoder->getElementStartTag(SYNC_ITEMOPERATIONS_OPTIONS)) && ($el[EN_FLAGS] & EN_FLAGS_CONTENT)) {
104
-						// TODO other options
105
-						// schema
106
-						// range
107
-						// username
108
-						// password
109
-						// bodypartpreference
110
-						// rm:RightsManagementSupport
111
-
112
-						WBXMLDecoder::ResetInWhile("itemOperationsOptions");
113
-						while (WBXMLDecoder::InWhile("itemOperationsOptions")) {
114
-							while (self::$decoder->getElementStartTag(SYNC_AIRSYNCBASE_BODYPREFERENCE)) {
115
-								if (self::$decoder->getElementStartTag(SYNC_AIRSYNCBASE_TYPE)) {
116
-									$bptype = self::$decoder->getElementContent();
117
-									$operation["cpo"]->BodyPreference($bptype);
118
-									if (!self::$decoder->getElementEndTag()) {
119
-										return false;
120
-									}
121
-								}
122
-
123
-								if (self::$decoder->getElementStartTag(SYNC_AIRSYNCBASE_TRUNCATIONSIZE)) {
124
-									$operation["cpo"]->BodyPreference($bptype)->SetTruncationSize(self::$decoder->getElementContent());
125
-									if (!self::$decoder->getElementEndTag()) {
126
-										return false;
127
-									}
128
-								}
129
-
130
-								if (self::$decoder->getElementStartTag(SYNC_AIRSYNCBASE_ALLORNONE)) {
131
-									$operation["cpo"]->BodyPreference($bptype)->SetAllOrNone(self::$decoder->getElementContent());
132
-									if (!self::$decoder->getElementEndTag()) {
133
-										return false;
134
-									}
135
-								}
136
-
137
-								if (self::$decoder->getElementStartTag(SYNC_AIRSYNCBASE_PREVIEW)) {
138
-									$operation["cpo"]->BodyPreference($bptype)->SetPreview(self::$decoder->getElementContent());
139
-									if (!self::$decoder->getElementEndTag()) {
140
-										return false;
141
-									}
142
-								}
143
-
144
-								if (!self::$decoder->getElementEndTag()) {
145
-									return false;
146
-								}// SYNC_AIRSYNCBASE_BODYPREFERENCE
147
-							}
148
-
149
-							if (self::$decoder->getElementStartTag(SYNC_AIRSYNCBASE_BODYPARTPREFERENCE)) {
150
-								if (self::$decoder->getElementStartTag(SYNC_AIRSYNCBASE_TYPE)) {
151
-									$bpptype = self::$decoder->getElementContent();
152
-									$operation["cpo"]->BodyPartPreference($bpptype);
153
-									if (!self::$decoder->getElementEndTag()) {
154
-										return false;
155
-									}
156
-								}
157
-
158
-								if (self::$decoder->getElementStartTag(SYNC_AIRSYNCBASE_TRUNCATIONSIZE)) {
159
-									$operation["cpo"]->BodyPartPreference($bpptype)->SetTruncationSize(self::$decoder->getElementContent());
160
-									if (!self::$decoder->getElementEndTag()) {
161
-										return false;
162
-									}
163
-								}
164
-
165
-								if (self::$decoder->getElementStartTag(SYNC_AIRSYNCBASE_ALLORNONE)) {
166
-									$operation["cpo"]->BodyPartPreference($bpptype)->SetAllOrNone(self::$decoder->getElementContent());
167
-									if (!self::$decoder->getElementEndTag()) {
168
-										return false;
169
-									}
170
-								}
171
-
172
-								if (self::$decoder->getElementStartTag(SYNC_AIRSYNCBASE_PREVIEW)) {
173
-									$operation["cpo"]->BodyPartPreference($bpptype)->SetPreview(self::$decoder->getElementContent());
174
-									if (!self::$decoder->getElementEndTag()) {
175
-										return false;
176
-									}
177
-								}
178
-
179
-								if (!self::$decoder->getElementEndTag()) {
180
-									return false;
181
-								}
182
-							}
183
-
184
-							if (self::$decoder->getElementStartTag(SYNC_MIMESUPPORT)) {
185
-								$operation["cpo"]->SetMimeSupport(self::$decoder->getElementContent());
186
-								if (!self::$decoder->getElementEndTag()) {
187
-									return false;
188
-								}
189
-							}
190
-
191
-							if (self::$decoder->getElementStartTag(SYNC_ITEMOPERATIONS_RANGE)) {
192
-								$operation["range"] = self::$decoder->getElementContent();
193
-								if (!self::$decoder->getElementEndTag()) {
194
-									return false;
195
-								}
196
-							}
197
-
198
-							if (self::$decoder->getElementStartTag(SYNC_ITEMOPERATIONS_SCHEMA)) {
199
-								// read schema tags
200
-								WBXMLDecoder::ResetInWhile("itemOperationsSchema");
201
-								while (WBXMLDecoder::InWhile("itemOperationsSchema")) {
202
-									// TODO save elements
203
-									$el = self::$decoder->getElement();
204
-									$e = self::$decoder->peek();
205
-									if ($e[EN_TYPE] == EN_TYPE_ENDTAG) {
206
-										self::$decoder->getElementEndTag();
207
-
208
-										break;
209
-									}
210
-								}
211
-							}
212
-
213
-							if (self::$decoder->getElementStartTag(SYNC_RIGHTSMANAGEMENT_SUPPORT)) {
214
-								$operation["cpo"]->SetRmSupport(self::$decoder->getElementContent());
215
-								if (!self::$decoder->getElementEndTag()) {
216
-									return false;
217
-								}
218
-							}
219
-
220
-							// break if it reached the endtag
221
-							$e = self::$decoder->peek();
222
-							if ($e[EN_TYPE] == EN_TYPE_ENDTAG) {
223
-								self::$decoder->getElementEndTag();
224
-
225
-								break;
226
-							}
227
-						}
228
-					}
229
-
230
-					if (self::$decoder->getElementStartTag(SYNC_RIGHTSMANAGEMENT_REMOVERIGHTSMGNTPROTECTION)) {
231
-						$operation["cpo"]->SetRemoveRmProtection(true);
232
-						if (($rrmp = self::$decoder->getElementContent()) !== false) {
233
-							$operation["cpo"]->SetRemoveRmProtection($rrmp);
234
-							if (!self::$decoder->getElementEndTag()) {
235
-								return false;
236
-							}
237
-						}
238
-					}
239
-				} // end if fetch
240
-
241
-				if ($efc) {
242
-					if (self::$decoder->getElementStartTag(SYNC_FOLDERID)) {
243
-						$operation['folderid'] = self::$decoder->getElementContent();
244
-						if (!self::$decoder->getElementEndTag()) {
245
-							return false;
246
-						}// SYNC_FOLDERID
247
-					}
248
-					if (self::$decoder->getElementStartTag(SYNC_ITEMOPERATIONS_OPTIONS)) {
249
-						if (self::$decoder->getElementStartTag(SYNC_ITEMOPERATIONS_DELETESUBFOLDERS)) {
250
-							$operation['deletesubfolders'] = true;
251
-							if (($dsf = self::$decoder->getElementContent()) !== false) {
252
-								$operation['deletesubfolders'] = (bool) $dsf;
253
-								if (!self::$decoder->getElementEndTag()) {
254
-									return false;
255
-								}
256
-							}
257
-						}
258
-						self::$decoder->getElementEndTag();
259
-					}
260
-				}
261
-
262
-				// TODO move
263
-
264
-				// break if it reached the endtag SYNC_ITEMOPERATIONS_FETCH or SYNC_ITEMOPERATIONS_EMPTYFOLDERCONTENTS or SYNC_ITEMOPERATIONS_MOVE
265
-				$e = self::$decoder->peek();
266
-				if ($e[EN_TYPE] == EN_TYPE_ENDTAG) {
267
-					self::$decoder->getElementEndTag();
268
-
269
-					break;
270
-				}
271
-			} // end while operation
272
-
273
-			// rewrite folderid into backendfolderid to be used on backend operations below
274
-			if (isset($operation['folderid'])) {
275
-				$operation['backendfolderid'] = self::$deviceManager->GetBackendIdForFolderId($operation['folderid']);
276
-			}
277
-
278
-			$itemoperations[] = $operation;
279
-			// break if it reached the endtag
280
-			$e = self::$decoder->peek();
281
-			if ($e[EN_TYPE] == EN_TYPE_ENDTAG) {
282
-				self::$decoder->getElementEndTag(); // SYNC_ITEMOPERATIONS_ITEMOPERATIONS
283
-
284
-				break;
285
-			}
286
-		} // end operations loop
287
-
288
-		$status = SYNC_ITEMOPERATIONSSTATUS_SUCCESS;
289
-
290
-		self::$encoder->startWBXML();
291
-
292
-		self::$encoder->startTag(SYNC_ITEMOPERATIONS_ITEMOPERATIONS);
293
-
294
-		self::$encoder->startTag(SYNC_ITEMOPERATIONS_STATUS);
295
-		self::$encoder->content($status);
296
-		self::$encoder->endTag(); // SYNC_ITEMOPERATIONS_STATUS
297
-
298
-		// Stop here if something went wrong
299
-		if ($status != SYNC_ITEMOPERATIONSSTATUS_SUCCESS) {
300
-			self::$encoder->endTag(); // SYNC_ITEMOPERATIONS_ITEMOPERATIONS
301
-
302
-			return true;
303
-		}
304
-
305
-		self::$encoder->startTag(SYNC_ITEMOPERATIONS_RESPONSE);
306
-
307
-		foreach ($itemoperations as $operation) {
308
-			// fetch response
309
-			if ($operation['operation'] == SYNC_ITEMOPERATIONS_FETCH) {
310
-				$status = SYNC_ITEMOPERATIONSSTATUS_SUCCESS;
311
-
312
-				// retrieve the data
313
-				// Fetch throws Sync status codes, - GetAttachmentData ItemOperations codes
314
-				if (isset($operation['filereference'])) {
315
-					try {
316
-						self::$topCollector->AnnounceInformation("Get attachment data from backend with file reference");
317
-						$data = self::$backend->GetAttachmentData($operation['filereference']);
318
-					}
319
-					catch (StatusException $stex) {
320
-						$status = $stex->getCode();
321
-					}
322
-				}
323
-				else {
324
-					try {
325
-						if (isset($operation['folderid'], $operation['serverid'])) {
326
-							self::$topCollector->AnnounceInformation("Fetching data from backend with item and folder id");
327
-							$data = self::$backend->Fetch($operation['backendfolderid'], $operation['serverid'], $operation["cpo"]);
328
-						}
329
-						elseif (isset($operation['longid'])) {
330
-							self::$topCollector->AnnounceInformation("Fetching data from backend with long id");
331
-							$tmp = explode(":", $operation['longid']);
332
-							$data = self::$backend->Fetch(self::$deviceManager->GetBackendIdForFolderId($tmp[0]), $tmp[1], $operation["cpo"]);
333
-						}
334
-					}
335
-					catch (StatusException $stex) {
336
-						// the only option to return is that we could not retrieve it
337
-						$status = SYNC_ITEMOPERATIONSSTATUS_CONVERSIONFAILED;
338
-					}
339
-				}
340
-
341
-				self::$encoder->startTag(SYNC_ITEMOPERATIONS_FETCH);
342
-
343
-				self::$encoder->startTag(SYNC_ITEMOPERATIONS_STATUS);
344
-				self::$encoder->content($status);
345
-				self::$encoder->endTag(); // SYNC_ITEMOPERATIONS_STATUS
346
-
347
-				if (isset($operation['folderid'], $operation['serverid'])) {
348
-					self::$encoder->startTag(SYNC_FOLDERID);
349
-					self::$encoder->content($operation['folderid']);
350
-					self::$encoder->endTag(); // end SYNC_FOLDERID
351
-
352
-					self::$encoder->startTag(SYNC_SERVERENTRYID);
353
-					self::$encoder->content($operation['serverid']);
354
-					self::$encoder->endTag(); // end SYNC_SERVERENTRYID
355
-
356
-					self::$encoder->startTag(SYNC_FOLDERTYPE);
357
-					self::$encoder->content("Email");
358
-					self::$encoder->endTag();
359
-				}
360
-
361
-				if (isset($operation['longid'])) {
362
-					self::$encoder->startTag(SYNC_SEARCH_LONGID);
363
-					self::$encoder->content($operation['longid']);
364
-					self::$encoder->endTag(); // end SYNC_FOLDERID
365
-
366
-					self::$encoder->startTag(SYNC_FOLDERTYPE);
367
-					self::$encoder->content("Email");
368
-					self::$encoder->endTag();
369
-				}
370
-
371
-				if (isset($operation['filereference'])) {
372
-					self::$encoder->startTag(SYNC_AIRSYNCBASE_FILEREFERENCE);
373
-					self::$encoder->content($operation['filereference']);
374
-					self::$encoder->endTag(); // end SYNC_AIRSYNCBASE_FILEREFERENCE
375
-				}
376
-
377
-				if (isset($data)) {
378
-					self::$topCollector->AnnounceInformation("Streaming data");
379
-
380
-					self::$encoder->startTag(SYNC_ITEMOPERATIONS_PROPERTIES);
381
-					if (isset($operation['range'])) {
382
-						self::$encoder->startTag(SYNC_ITEMOPERATIONS_RANGE);
383
-						self::$encoder->content($operation['range']);
384
-						self::$encoder->endTag(); // SYNC_ITEMOPERATIONS_RANGE
385
-					}
386
-					$data->Encode(self::$encoder);
387
-					self::$encoder->endTag(); // SYNC_ITEMOPERATIONS_PROPERTIES
388
-				}
389
-
390
-				self::$encoder->endTag(); // SYNC_ITEMOPERATIONS_FETCH
391
-			}
392
-			// empty folder contents operation
393
-			elseif ($operation['operation'] == SYNC_ITEMOPERATIONS_EMPTYFOLDERCONTENTS) {
394
-				try {
395
-					self::$topCollector->AnnounceInformation("Emptying folder");
396
-
397
-					// send request to backend
398
-					self::$backend->EmptyFolder($operation['backendfolderid'], $operation['deletesubfolders']);
399
-				}
400
-				catch (StatusException $stex) {
401
-					$status = $stex->getCode();
402
-				}
403
-
404
-				self::$encoder->startTag(SYNC_ITEMOPERATIONS_EMPTYFOLDERCONTENTS);
405
-
406
-				self::$encoder->startTag(SYNC_ITEMOPERATIONS_STATUS);
407
-				self::$encoder->content($status);
408
-				self::$encoder->endTag(); // SYNC_ITEMOPERATIONS_STATUS
409
-
410
-				if (isset($operation['folderid'])) {
411
-					self::$encoder->startTag(SYNC_FOLDERID);
412
-					self::$encoder->content($operation['folderid']);
413
-					self::$encoder->endTag(); // end SYNC_FOLDERID
414
-				}
415
-				self::$encoder->endTag(); // SYNC_ITEMOPERATIONS_EMPTYFOLDERCONTENTS
416
-			}
417
-			// TODO implement ItemOperations Move
418
-			// move operation
419
-			else {
420
-				self::$topCollector->AnnounceInformation("not implemented", true);
421
-
422
-				// reply with "can't do"
423
-				self::$encoder->startTag(SYNC_ITEMOPERATIONS_MOVE);
424
-				self::$encoder->startTag(SYNC_ITEMOPERATIONS_STATUS);
425
-				self::$encoder->content(SYNC_ITEMOPERATIONSSTATUS_SERVERERROR);
426
-				self::$encoder->endTag(); // SYNC_ITEMOPERATIONS_STATUS
427
-				self::$encoder->endTag(); // SYNC_ITEMOPERATIONS_MOVE
428
-			}
429
-		}
430
-		self::$encoder->endTag(); // SYNC_ITEMOPERATIONS_RESPONSE
431
-		self::$encoder->endTag(); // SYNC_ITEMOPERATIONS_ITEMOPERATIONS
432
-
433
-		return true;
434
-	}
11
+    /**
12
+     * Handles the ItemOperations command
13
+     * Provides batched online handling for Fetch, EmptyFolderContents and Move.
14
+     *
15
+     * @param int $commandCode
16
+     *
17
+     * @return bool
18
+     */
19
+    public function Handle($commandCode) {
20
+        // Parse input
21
+        if (!self::$decoder->getElementStartTag(SYNC_ITEMOPERATIONS_ITEMOPERATIONS)) {
22
+            return false;
23
+        }
24
+
25
+        $itemoperations = [];
26
+        // ItemOperations can either be Fetch, EmptyFolderContents or Move
27
+        WBXMLDecoder::ResetInWhile("itemOperationsActions");
28
+        while (WBXMLDecoder::InWhile("itemOperationsActions")) {
29
+            // TODO check if multiple item operations are possible in one request
30
+            $el = self::$decoder->getElement();
31
+
32
+            if ($el[EN_TYPE] != EN_TYPE_STARTTAG) {
33
+                return false;
34
+            }
35
+
36
+            $fetch = $efc = $move = false;
37
+            $operation = [];
38
+            if ($el[EN_TAG] == SYNC_ITEMOPERATIONS_FETCH) {
39
+                $fetch = true;
40
+                $operation['operation'] = SYNC_ITEMOPERATIONS_FETCH;
41
+                self::$topCollector->AnnounceInformation("Fetch", true);
42
+            }
43
+            elseif ($el[EN_TAG] == SYNC_ITEMOPERATIONS_EMPTYFOLDERCONTENTS) {
44
+                $efc = true;
45
+                $operation['operation'] = SYNC_ITEMOPERATIONS_EMPTYFOLDERCONTENTS;
46
+                self::$topCollector->AnnounceInformation("Empty Folder", true);
47
+            }
48
+            elseif ($el[EN_TAG] == SYNC_ITEMOPERATIONS_MOVE) {
49
+                $move = true;
50
+                $operation['operation'] = SYNC_ITEMOPERATIONS_MOVE;
51
+                self::$topCollector->AnnounceInformation("Move", true);
52
+            }
53
+
54
+            if (!$fetch && !$efc && !$move) {
55
+                SLog::Write(LOGLEVEL_DEBUG, "Unknown item operation:" . print_r($el, 1));
56
+                self::$topCollector->AnnounceInformation("Unknown operation", true);
57
+
58
+                return false;
59
+            }
60
+
61
+            // process operation
62
+            WBXMLDecoder::ResetInWhile("itemOperationsOperation");
63
+            while (WBXMLDecoder::InWhile("itemOperationsOperation")) {
64
+                if ($fetch) {
65
+                    // Save all OPTIONS into a ContentParameters object
66
+                    $operation["cpo"] = new ContentParameters();
67
+
68
+                    if (self::$decoder->getElementStartTag(SYNC_ITEMOPERATIONS_STORE)) {
69
+                        $operation['store'] = self::$decoder->getElementContent();
70
+                        if (!self::$decoder->getElementEndTag()) {
71
+                            return false;
72
+                        }// SYNC_ITEMOPERATIONS_STORE
73
+                    }
74
+
75
+                    if (self::$decoder->getElementStartTag(SYNC_SEARCH_LONGID)) {
76
+                        $operation['longid'] = self::$decoder->getElementContent();
77
+                        if (!self::$decoder->getElementEndTag()) {
78
+                            return false;
79
+                        }// SYNC_SEARCH_LONGID
80
+                    }
81
+
82
+                    if (self::$decoder->getElementStartTag(SYNC_FOLDERID)) {
83
+                        $operation['folderid'] = self::$decoder->getElementContent();
84
+                        if (!self::$decoder->getElementEndTag()) {
85
+                            return false;
86
+                        }// SYNC_FOLDERID
87
+                    }
88
+
89
+                    if (self::$decoder->getElementStartTag(SYNC_SERVERENTRYID)) {
90
+                        $operation['serverid'] = self::$decoder->getElementContent();
91
+                        if (!self::$decoder->getElementEndTag()) {
92
+                            return false;
93
+                        }// SYNC_SERVERENTRYID
94
+                    }
95
+
96
+                    if (self::$decoder->getElementStartTag(SYNC_AIRSYNCBASE_FILEREFERENCE)) {
97
+                        $operation['filereference'] = self::$decoder->getElementContent();
98
+                        if (!self::$decoder->getElementEndTag()) {
99
+                            return false;
100
+                        }// SYNC_AIRSYNCBASE_FILEREFERENCE
101
+                    }
102
+
103
+                    if (($el = self::$decoder->getElementStartTag(SYNC_ITEMOPERATIONS_OPTIONS)) && ($el[EN_FLAGS] & EN_FLAGS_CONTENT)) {
104
+                        // TODO other options
105
+                        // schema
106
+                        // range
107
+                        // username
108
+                        // password
109
+                        // bodypartpreference
110
+                        // rm:RightsManagementSupport
111
+
112
+                        WBXMLDecoder::ResetInWhile("itemOperationsOptions");
113
+                        while (WBXMLDecoder::InWhile("itemOperationsOptions")) {
114
+                            while (self::$decoder->getElementStartTag(SYNC_AIRSYNCBASE_BODYPREFERENCE)) {
115
+                                if (self::$decoder->getElementStartTag(SYNC_AIRSYNCBASE_TYPE)) {
116
+                                    $bptype = self::$decoder->getElementContent();
117
+                                    $operation["cpo"]->BodyPreference($bptype);
118
+                                    if (!self::$decoder->getElementEndTag()) {
119
+                                        return false;
120
+                                    }
121
+                                }
122
+
123
+                                if (self::$decoder->getElementStartTag(SYNC_AIRSYNCBASE_TRUNCATIONSIZE)) {
124
+                                    $operation["cpo"]->BodyPreference($bptype)->SetTruncationSize(self::$decoder->getElementContent());
125
+                                    if (!self::$decoder->getElementEndTag()) {
126
+                                        return false;
127
+                                    }
128
+                                }
129
+
130
+                                if (self::$decoder->getElementStartTag(SYNC_AIRSYNCBASE_ALLORNONE)) {
131
+                                    $operation["cpo"]->BodyPreference($bptype)->SetAllOrNone(self::$decoder->getElementContent());
132
+                                    if (!self::$decoder->getElementEndTag()) {
133
+                                        return false;
134
+                                    }
135
+                                }
136
+
137
+                                if (self::$decoder->getElementStartTag(SYNC_AIRSYNCBASE_PREVIEW)) {
138
+                                    $operation["cpo"]->BodyPreference($bptype)->SetPreview(self::$decoder->getElementContent());
139
+                                    if (!self::$decoder->getElementEndTag()) {
140
+                                        return false;
141
+                                    }
142
+                                }
143
+
144
+                                if (!self::$decoder->getElementEndTag()) {
145
+                                    return false;
146
+                                }// SYNC_AIRSYNCBASE_BODYPREFERENCE
147
+                            }
148
+
149
+                            if (self::$decoder->getElementStartTag(SYNC_AIRSYNCBASE_BODYPARTPREFERENCE)) {
150
+                                if (self::$decoder->getElementStartTag(SYNC_AIRSYNCBASE_TYPE)) {
151
+                                    $bpptype = self::$decoder->getElementContent();
152
+                                    $operation["cpo"]->BodyPartPreference($bpptype);
153
+                                    if (!self::$decoder->getElementEndTag()) {
154
+                                        return false;
155
+                                    }
156
+                                }
157
+
158
+                                if (self::$decoder->getElementStartTag(SYNC_AIRSYNCBASE_TRUNCATIONSIZE)) {
159
+                                    $operation["cpo"]->BodyPartPreference($bpptype)->SetTruncationSize(self::$decoder->getElementContent());
160
+                                    if (!self::$decoder->getElementEndTag()) {
161
+                                        return false;
162
+                                    }
163
+                                }
164
+
165
+                                if (self::$decoder->getElementStartTag(SYNC_AIRSYNCBASE_ALLORNONE)) {
166
+                                    $operation["cpo"]->BodyPartPreference($bpptype)->SetAllOrNone(self::$decoder->getElementContent());
167
+                                    if (!self::$decoder->getElementEndTag()) {
168
+                                        return false;
169
+                                    }
170
+                                }
171
+
172
+                                if (self::$decoder->getElementStartTag(SYNC_AIRSYNCBASE_PREVIEW)) {
173
+                                    $operation["cpo"]->BodyPartPreference($bpptype)->SetPreview(self::$decoder->getElementContent());
174
+                                    if (!self::$decoder->getElementEndTag()) {
175
+                                        return false;
176
+                                    }
177
+                                }
178
+
179
+                                if (!self::$decoder->getElementEndTag()) {
180
+                                    return false;
181
+                                }
182
+                            }
183
+
184
+                            if (self::$decoder->getElementStartTag(SYNC_MIMESUPPORT)) {
185
+                                $operation["cpo"]->SetMimeSupport(self::$decoder->getElementContent());
186
+                                if (!self::$decoder->getElementEndTag()) {
187
+                                    return false;
188
+                                }
189
+                            }
190
+
191
+                            if (self::$decoder->getElementStartTag(SYNC_ITEMOPERATIONS_RANGE)) {
192
+                                $operation["range"] = self::$decoder->getElementContent();
193
+                                if (!self::$decoder->getElementEndTag()) {
194
+                                    return false;
195
+                                }
196
+                            }
197
+
198
+                            if (self::$decoder->getElementStartTag(SYNC_ITEMOPERATIONS_SCHEMA)) {
199
+                                // read schema tags
200
+                                WBXMLDecoder::ResetInWhile("itemOperationsSchema");
201
+                                while (WBXMLDecoder::InWhile("itemOperationsSchema")) {
202
+                                    // TODO save elements
203
+                                    $el = self::$decoder->getElement();
204
+                                    $e = self::$decoder->peek();
205
+                                    if ($e[EN_TYPE] == EN_TYPE_ENDTAG) {
206
+                                        self::$decoder->getElementEndTag();
207
+
208
+                                        break;
209
+                                    }
210
+                                }
211
+                            }
212
+
213
+                            if (self::$decoder->getElementStartTag(SYNC_RIGHTSMANAGEMENT_SUPPORT)) {
214
+                                $operation["cpo"]->SetRmSupport(self::$decoder->getElementContent());
215
+                                if (!self::$decoder->getElementEndTag()) {
216
+                                    return false;
217
+                                }
218
+                            }
219
+
220
+                            // break if it reached the endtag
221
+                            $e = self::$decoder->peek();
222
+                            if ($e[EN_TYPE] == EN_TYPE_ENDTAG) {
223
+                                self::$decoder->getElementEndTag();
224
+
225
+                                break;
226
+                            }
227
+                        }
228
+                    }
229
+
230
+                    if (self::$decoder->getElementStartTag(SYNC_RIGHTSMANAGEMENT_REMOVERIGHTSMGNTPROTECTION)) {
231
+                        $operation["cpo"]->SetRemoveRmProtection(true);
232
+                        if (($rrmp = self::$decoder->getElementContent()) !== false) {
233
+                            $operation["cpo"]->SetRemoveRmProtection($rrmp);
234
+                            if (!self::$decoder->getElementEndTag()) {
235
+                                return false;
236
+                            }
237
+                        }
238
+                    }
239
+                } // end if fetch
240
+
241
+                if ($efc) {
242
+                    if (self::$decoder->getElementStartTag(SYNC_FOLDERID)) {
243
+                        $operation['folderid'] = self::$decoder->getElementContent();
244
+                        if (!self::$decoder->getElementEndTag()) {
245
+                            return false;
246
+                        }// SYNC_FOLDERID
247
+                    }
248
+                    if (self::$decoder->getElementStartTag(SYNC_ITEMOPERATIONS_OPTIONS)) {
249
+                        if (self::$decoder->getElementStartTag(SYNC_ITEMOPERATIONS_DELETESUBFOLDERS)) {
250
+                            $operation['deletesubfolders'] = true;
251
+                            if (($dsf = self::$decoder->getElementContent()) !== false) {
252
+                                $operation['deletesubfolders'] = (bool) $dsf;
253
+                                if (!self::$decoder->getElementEndTag()) {
254
+                                    return false;
255
+                                }
256
+                            }
257
+                        }
258
+                        self::$decoder->getElementEndTag();
259
+                    }
260
+                }
261
+
262
+                // TODO move
263
+
264
+                // break if it reached the endtag SYNC_ITEMOPERATIONS_FETCH or SYNC_ITEMOPERATIONS_EMPTYFOLDERCONTENTS or SYNC_ITEMOPERATIONS_MOVE
265
+                $e = self::$decoder->peek();
266
+                if ($e[EN_TYPE] == EN_TYPE_ENDTAG) {
267
+                    self::$decoder->getElementEndTag();
268
+
269
+                    break;
270
+                }
271
+            } // end while operation
272
+
273
+            // rewrite folderid into backendfolderid to be used on backend operations below
274
+            if (isset($operation['folderid'])) {
275
+                $operation['backendfolderid'] = self::$deviceManager->GetBackendIdForFolderId($operation['folderid']);
276
+            }
277
+
278
+            $itemoperations[] = $operation;
279
+            // break if it reached the endtag
280
+            $e = self::$decoder->peek();
281
+            if ($e[EN_TYPE] == EN_TYPE_ENDTAG) {
282
+                self::$decoder->getElementEndTag(); // SYNC_ITEMOPERATIONS_ITEMOPERATIONS
283
+
284
+                break;
285
+            }
286
+        } // end operations loop
287
+
288
+        $status = SYNC_ITEMOPERATIONSSTATUS_SUCCESS;
289
+
290
+        self::$encoder->startWBXML();
291
+
292
+        self::$encoder->startTag(SYNC_ITEMOPERATIONS_ITEMOPERATIONS);
293
+
294
+        self::$encoder->startTag(SYNC_ITEMOPERATIONS_STATUS);
295
+        self::$encoder->content($status);
296
+        self::$encoder->endTag(); // SYNC_ITEMOPERATIONS_STATUS
297
+
298
+        // Stop here if something went wrong
299
+        if ($status != SYNC_ITEMOPERATIONSSTATUS_SUCCESS) {
300
+            self::$encoder->endTag(); // SYNC_ITEMOPERATIONS_ITEMOPERATIONS
301
+
302
+            return true;
303
+        }
304
+
305
+        self::$encoder->startTag(SYNC_ITEMOPERATIONS_RESPONSE);
306
+
307
+        foreach ($itemoperations as $operation) {
308
+            // fetch response
309
+            if ($operation['operation'] == SYNC_ITEMOPERATIONS_FETCH) {
310
+                $status = SYNC_ITEMOPERATIONSSTATUS_SUCCESS;
311
+
312
+                // retrieve the data
313
+                // Fetch throws Sync status codes, - GetAttachmentData ItemOperations codes
314
+                if (isset($operation['filereference'])) {
315
+                    try {
316
+                        self::$topCollector->AnnounceInformation("Get attachment data from backend with file reference");
317
+                        $data = self::$backend->GetAttachmentData($operation['filereference']);
318
+                    }
319
+                    catch (StatusException $stex) {
320
+                        $status = $stex->getCode();
321
+                    }
322
+                }
323
+                else {
324
+                    try {
325
+                        if (isset($operation['folderid'], $operation['serverid'])) {
326
+                            self::$topCollector->AnnounceInformation("Fetching data from backend with item and folder id");
327
+                            $data = self::$backend->Fetch($operation['backendfolderid'], $operation['serverid'], $operation["cpo"]);
328
+                        }
329
+                        elseif (isset($operation['longid'])) {
330
+                            self::$topCollector->AnnounceInformation("Fetching data from backend with long id");
331
+                            $tmp = explode(":", $operation['longid']);
332
+                            $data = self::$backend->Fetch(self::$deviceManager->GetBackendIdForFolderId($tmp[0]), $tmp[1], $operation["cpo"]);
333
+                        }
334
+                    }
335
+                    catch (StatusException $stex) {
336
+                        // the only option to return is that we could not retrieve it
337
+                        $status = SYNC_ITEMOPERATIONSSTATUS_CONVERSIONFAILED;
338
+                    }
339
+                }
340
+
341
+                self::$encoder->startTag(SYNC_ITEMOPERATIONS_FETCH);
342
+
343
+                self::$encoder->startTag(SYNC_ITEMOPERATIONS_STATUS);
344
+                self::$encoder->content($status);
345
+                self::$encoder->endTag(); // SYNC_ITEMOPERATIONS_STATUS
346
+
347
+                if (isset($operation['folderid'], $operation['serverid'])) {
348
+                    self::$encoder->startTag(SYNC_FOLDERID);
349
+                    self::$encoder->content($operation['folderid']);
350
+                    self::$encoder->endTag(); // end SYNC_FOLDERID
351
+
352
+                    self::$encoder->startTag(SYNC_SERVERENTRYID);
353
+                    self::$encoder->content($operation['serverid']);
354
+                    self::$encoder->endTag(); // end SYNC_SERVERENTRYID
355
+
356
+                    self::$encoder->startTag(SYNC_FOLDERTYPE);
357
+                    self::$encoder->content("Email");
358
+                    self::$encoder->endTag();
359
+                }
360
+
361
+                if (isset($operation['longid'])) {
362
+                    self::$encoder->startTag(SYNC_SEARCH_LONGID);
363
+                    self::$encoder->content($operation['longid']);
364
+                    self::$encoder->endTag(); // end SYNC_FOLDERID
365
+
366
+                    self::$encoder->startTag(SYNC_FOLDERTYPE);
367
+                    self::$encoder->content("Email");
368
+                    self::$encoder->endTag();
369
+                }
370
+
371
+                if (isset($operation['filereference'])) {
372
+                    self::$encoder->startTag(SYNC_AIRSYNCBASE_FILEREFERENCE);
373
+                    self::$encoder->content($operation['filereference']);
374
+                    self::$encoder->endTag(); // end SYNC_AIRSYNCBASE_FILEREFERENCE
375
+                }
376
+
377
+                if (isset($data)) {
378
+                    self::$topCollector->AnnounceInformation("Streaming data");
379
+
380
+                    self::$encoder->startTag(SYNC_ITEMOPERATIONS_PROPERTIES);
381
+                    if (isset($operation['range'])) {
382
+                        self::$encoder->startTag(SYNC_ITEMOPERATIONS_RANGE);
383
+                        self::$encoder->content($operation['range']);
384
+                        self::$encoder->endTag(); // SYNC_ITEMOPERATIONS_RANGE
385
+                    }
386
+                    $data->Encode(self::$encoder);
387
+                    self::$encoder->endTag(); // SYNC_ITEMOPERATIONS_PROPERTIES
388
+                }
389
+
390
+                self::$encoder->endTag(); // SYNC_ITEMOPERATIONS_FETCH
391
+            }
392
+            // empty folder contents operation
393
+            elseif ($operation['operation'] == SYNC_ITEMOPERATIONS_EMPTYFOLDERCONTENTS) {
394
+                try {
395
+                    self::$topCollector->AnnounceInformation("Emptying folder");
396
+
397
+                    // send request to backend
398
+                    self::$backend->EmptyFolder($operation['backendfolderid'], $operation['deletesubfolders']);
399
+                }
400
+                catch (StatusException $stex) {
401
+                    $status = $stex->getCode();
402
+                }
403
+
404
+                self::$encoder->startTag(SYNC_ITEMOPERATIONS_EMPTYFOLDERCONTENTS);
405
+
406
+                self::$encoder->startTag(SYNC_ITEMOPERATIONS_STATUS);
407
+                self::$encoder->content($status);
408
+                self::$encoder->endTag(); // SYNC_ITEMOPERATIONS_STATUS
409
+
410
+                if (isset($operation['folderid'])) {
411
+                    self::$encoder->startTag(SYNC_FOLDERID);
412
+                    self::$encoder->content($operation['folderid']);
413
+                    self::$encoder->endTag(); // end SYNC_FOLDERID
414
+                }
415
+                self::$encoder->endTag(); // SYNC_ITEMOPERATIONS_EMPTYFOLDERCONTENTS
416
+            }
417
+            // TODO implement ItemOperations Move
418
+            // move operation
419
+            else {
420
+                self::$topCollector->AnnounceInformation("not implemented", true);
421
+
422
+                // reply with "can't do"
423
+                self::$encoder->startTag(SYNC_ITEMOPERATIONS_MOVE);
424
+                self::$encoder->startTag(SYNC_ITEMOPERATIONS_STATUS);
425
+                self::$encoder->content(SYNC_ITEMOPERATIONSSTATUS_SERVERERROR);
426
+                self::$encoder->endTag(); // SYNC_ITEMOPERATIONS_STATUS
427
+                self::$encoder->endTag(); // SYNC_ITEMOPERATIONS_MOVE
428
+            }
429
+        }
430
+        self::$encoder->endTag(); // SYNC_ITEMOPERATIONS_RESPONSE
431
+        self::$encoder->endTag(); // SYNC_ITEMOPERATIONS_ITEMOPERATIONS
432
+
433
+        return true;
434
+    }
435 435
 }
Please login to merge, or discard this patch.
Spacing   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -52,7 +52,7 @@  discard block
 block discarded – undo
52 52
 			}
53 53
 
54 54
 			if (!$fetch && !$efc && !$move) {
55
-				SLog::Write(LOGLEVEL_DEBUG, "Unknown item operation:" . print_r($el, 1));
55
+				SLog::Write(LOGLEVEL_DEBUG, "Unknown item operation:".print_r($el, 1));
56 56
 				self::$topCollector->AnnounceInformation("Unknown operation", true);
57 57
 
58 58
 				return false;
@@ -249,7 +249,7 @@  discard block
 block discarded – undo
249 249
 						if (self::$decoder->getElementStartTag(SYNC_ITEMOPERATIONS_DELETESUBFOLDERS)) {
250 250
 							$operation['deletesubfolders'] = true;
251 251
 							if (($dsf = self::$decoder->getElementContent()) !== false) {
252
-								$operation['deletesubfolders'] = (bool) $dsf;
252
+								$operation['deletesubfolders'] = (bool)$dsf;
253 253
 								if (!self::$decoder->getElementEndTag()) {
254 254
 									return false;
255 255
 								}
Please login to merge, or discard this patch.
Braces   +7 added lines, -14 removed lines patch added patch discarded remove patch
@@ -39,13 +39,11 @@  discard block
 block discarded – undo
39 39
 				$fetch = true;
40 40
 				$operation['operation'] = SYNC_ITEMOPERATIONS_FETCH;
41 41
 				self::$topCollector->AnnounceInformation("Fetch", true);
42
-			}
43
-			elseif ($el[EN_TAG] == SYNC_ITEMOPERATIONS_EMPTYFOLDERCONTENTS) {
42
+			} elseif ($el[EN_TAG] == SYNC_ITEMOPERATIONS_EMPTYFOLDERCONTENTS) {
44 43
 				$efc = true;
45 44
 				$operation['operation'] = SYNC_ITEMOPERATIONS_EMPTYFOLDERCONTENTS;
46 45
 				self::$topCollector->AnnounceInformation("Empty Folder", true);
47
-			}
48
-			elseif ($el[EN_TAG] == SYNC_ITEMOPERATIONS_MOVE) {
46
+			} elseif ($el[EN_TAG] == SYNC_ITEMOPERATIONS_MOVE) {
49 47
 				$move = true;
50 48
 				$operation['operation'] = SYNC_ITEMOPERATIONS_MOVE;
51 49
 				self::$topCollector->AnnounceInformation("Move", true);
@@ -315,24 +313,20 @@  discard block
 block discarded – undo
315 313
 					try {
316 314
 						self::$topCollector->AnnounceInformation("Get attachment data from backend with file reference");
317 315
 						$data = self::$backend->GetAttachmentData($operation['filereference']);
318
-					}
319
-					catch (StatusException $stex) {
316
+					} catch (StatusException $stex) {
320 317
 						$status = $stex->getCode();
321 318
 					}
322
-				}
323
-				else {
319
+				} else {
324 320
 					try {
325 321
 						if (isset($operation['folderid'], $operation['serverid'])) {
326 322
 							self::$topCollector->AnnounceInformation("Fetching data from backend with item and folder id");
327 323
 							$data = self::$backend->Fetch($operation['backendfolderid'], $operation['serverid'], $operation["cpo"]);
328
-						}
329
-						elseif (isset($operation['longid'])) {
324
+						} elseif (isset($operation['longid'])) {
330 325
 							self::$topCollector->AnnounceInformation("Fetching data from backend with long id");
331 326
 							$tmp = explode(":", $operation['longid']);
332 327
 							$data = self::$backend->Fetch(self::$deviceManager->GetBackendIdForFolderId($tmp[0]), $tmp[1], $operation["cpo"]);
333 328
 						}
334
-					}
335
-					catch (StatusException $stex) {
329
+					} catch (StatusException $stex) {
336 330
 						// the only option to return is that we could not retrieve it
337 331
 						$status = SYNC_ITEMOPERATIONSSTATUS_CONVERSIONFAILED;
338 332
 					}
@@ -396,8 +390,7 @@  discard block
 block discarded – undo
396 390
 
397 391
 					// send request to backend
398 392
 					self::$backend->EmptyFolder($operation['backendfolderid'], $operation['deletesubfolders']);
399
-				}
400
-				catch (StatusException $stex) {
393
+				} catch (StatusException $stex) {
401 394
 					$status = $stex->getCode();
402 395
 				}
403 396
 
Please login to merge, or discard this patch.
lib/request/notify.php 1 patch
Indentation   +30 added lines, -30 removed lines patch added patch discarded remove patch
@@ -8,43 +8,43 @@
 block discarded – undo
8 8
  */
9 9
 
10 10
 class Notify extends RequestProcessor {
11
-	/**
12
-	 * Handles the Notify command.
13
-	 *
14
-	 * @param int $commandCode
15
-	 *
16
-	 * @return bool
17
-	 */
18
-	public function Handle($commandCode) {
19
-		if (!self::$decoder->getElementStartTag(SYNC_AIRNOTIFY_NOTIFY)) {
20
-			return false;
21
-		}
11
+    /**
12
+     * Handles the Notify command.
13
+     *
14
+     * @param int $commandCode
15
+     *
16
+     * @return bool
17
+     */
18
+    public function Handle($commandCode) {
19
+        if (!self::$decoder->getElementStartTag(SYNC_AIRNOTIFY_NOTIFY)) {
20
+            return false;
21
+        }
22 22
 
23
-		if (!self::$decoder->getElementStartTag(SYNC_AIRNOTIFY_DEVICEINFO)) {
24
-			return false;
25
-		}
23
+        if (!self::$decoder->getElementStartTag(SYNC_AIRNOTIFY_DEVICEINFO)) {
24
+            return false;
25
+        }
26 26
 
27
-		if (!self::$decoder->getElementEndTag()) {
28
-			return false;
29
-		}
27
+        if (!self::$decoder->getElementEndTag()) {
28
+            return false;
29
+        }
30 30
 
31
-		if (!self::$decoder->getElementEndTag()) {
32
-			return false;
33
-		}
31
+        if (!self::$decoder->getElementEndTag()) {
32
+            return false;
33
+        }
34 34
 
35
-		self::$encoder->StartWBXML();
35
+        self::$encoder->StartWBXML();
36 36
 
37
-		self::$encoder->startTag(SYNC_AIRNOTIFY_NOTIFY);
37
+        self::$encoder->startTag(SYNC_AIRNOTIFY_NOTIFY);
38 38
 
39
-		self::$encoder->startTag(SYNC_AIRNOTIFY_STATUS);
40
-		self::$encoder->content(1);
41
-		self::$encoder->endTag();
39
+        self::$encoder->startTag(SYNC_AIRNOTIFY_STATUS);
40
+        self::$encoder->content(1);
41
+        self::$encoder->endTag();
42 42
 
43
-		self::$encoder->startTag(SYNC_AIRNOTIFY_VALIDCARRIERPROFILES);
44
-		self::$encoder->endTag();
43
+        self::$encoder->startTag(SYNC_AIRNOTIFY_VALIDCARRIERPROFILES);
44
+        self::$encoder->endTag();
45 45
 
46
-		self::$encoder->endTag();
46
+        self::$encoder->endTag();
47 47
 
48
-		return true;
49
-	}
48
+        return true;
49
+    }
50 50
 }
Please login to merge, or discard this patch.
lib/request/provisioning.php 2 patches
Indentation   +241 added lines, -241 removed lines patch added patch discarded remove patch
@@ -8,245 +8,245 @@
 block discarded – undo
8 8
  */
9 9
 
10 10
 class Provisioning extends RequestProcessor {
11
-	/**
12
-	 * Handles the Provisioning command.
13
-	 *
14
-	 * @param int $commandCode
15
-	 *
16
-	 * @return bool
17
-	 */
18
-	public function Handle($commandCode) {
19
-		$status = SYNC_PROVISION_STATUS_SUCCESS;
20
-		$policystatus = SYNC_PROVISION_POLICYSTATUS_SUCCESS;
21
-
22
-		$rwstatus = GSync::GetProvisioningManager()->GetProvisioningWipeStatus();
23
-		$rwstatusWiped = false;
24
-		$deviceInfoSet = false;
25
-		$wipeRequest = !($rwstatus < SYNC_PROVISION_RWSTATUS_PENDING);
26
-
27
-		// if this is a regular provisioning require that an authenticated remote user
28
-		if (!$wipeRequest) {
29
-			SLog::Write(LOGLEVEL_DEBUG, "RequestProcessor::HandleProvision(): Forcing delayed Authentication");
30
-			self::Authenticate();
31
-		}
32
-
33
-		$phase2 = true;
34
-
35
-		if (!self::$decoder->getElementStartTag(SYNC_PROVISION_PROVISION)) {
36
-			return false;
37
-		}
38
-
39
-		// Loop through Provision request tags. Possible are:
40
-		// - Remote Wipe
41
-		// - DeviceInformation
42
-		// - Policies
43
-		// Each of them should only be once per request.
44
-		WBXMLDecoder::ResetInWhile("provisioningMain");
45
-		while (WBXMLDecoder::InWhile("provisioningMain")) {
46
-			$requestName = "";
47
-			if (self::$decoder->getElementStartTag(SYNC_PROVISION_REMOTEWIPE)) {
48
-				$requestName = SYNC_PROVISION_REMOTEWIPE;
49
-			}
50
-			if (self::$decoder->getElementStartTag(SYNC_PROVISION_POLICIES)) {
51
-				$requestName = SYNC_PROVISION_POLICIES;
52
-			}
53
-			if (self::$decoder->getElementStartTag(SYNC_SETTINGS_DEVICEINFORMATION)) {
54
-				$requestName = SYNC_SETTINGS_DEVICEINFORMATION;
55
-			}
56
-
57
-			if (!$requestName) {
58
-				break;
59
-			}
60
-
61
-			// set is available for OOF, device password and device information
62
-			switch ($requestName) {
63
-				case SYNC_PROVISION_REMOTEWIPE:
64
-					if (!self::$decoder->getElementStartTag(SYNC_PROVISION_STATUS)) {
65
-						return false;
66
-					}
67
-
68
-					$instatus = self::$decoder->getElementContent();
69
-
70
-					if (!self::$decoder->getElementEndTag()) {
71
-						return false;
72
-					}
73
-
74
-					if (!self::$decoder->getElementEndTag()) {
75
-						return false;
76
-					}
77
-
78
-					$phase2 = false;
79
-					$rwstatusWiped = true;
80
-					// TODO check - do it after while(1) finished?
81
-					break;
82
-
83
-				case SYNC_PROVISION_POLICIES:
84
-					if (!self::$decoder->getElementStartTag(SYNC_PROVISION_POLICY)) {
85
-						return false;
86
-					}
87
-
88
-					if (!self::$decoder->getElementStartTag(SYNC_PROVISION_POLICYTYPE)) {
89
-						return false;
90
-					}
91
-
92
-					$policytype = self::$decoder->getElementContent();
93
-					if ($policytype != 'MS-WAP-Provisioning-XML' && $policytype != 'MS-EAS-Provisioning-WBXML') {
94
-						$status = SYNC_PROVISION_STATUS_SERVERERROR;
95
-					}
96
-					if (!self::$decoder->getElementEndTag()) { // policytype
97
-						return false;
98
-					}
99
-
100
-					if (self::$decoder->getElementStartTag(SYNC_PROVISION_POLICYKEY)) {
101
-						$devpolicykey = self::$decoder->getElementContent();
102
-
103
-						if (!self::$decoder->getElementEndTag()) {
104
-							return false;
105
-						}
106
-
107
-						if (!self::$decoder->getElementStartTag(SYNC_PROVISION_STATUS)) {
108
-							return false;
109
-						}
110
-
111
-						$instatus = self::$decoder->getElementContent();
112
-
113
-						if (!self::$decoder->getElementEndTag()) {
114
-							return false;
115
-						}
116
-
117
-						$phase2 = false;
118
-					}
119
-
120
-					if (!self::$decoder->getElementEndTag()) { // policy
121
-						return false;
122
-					}
123
-
124
-					if (!self::$decoder->getElementEndTag()) { // policies
125
-						return false;
126
-					}
127
-					break;
128
-
129
-				case SYNC_SETTINGS_DEVICEINFORMATION:
130
-					// AS14.1 and later clients pass Device Information on the initial Provision request
131
-					if (!self::$decoder->getElementStartTag(SYNC_SETTINGS_SET)) {
132
-						return false;
133
-					}
134
-					$deviceInfoSet = true;
135
-					$deviceinformation = new SyncDeviceInformation();
136
-					$deviceinformation->Decode(self::$decoder);
137
-					$deviceinformation->Status = SYNC_SETTINGSSTATUS_SUCCESS;
138
-					if (!$wipeRequest) {
139
-						// for this operation the device manager is available
140
-						GSync::GetDeviceManager()->SaveDeviceInformation($deviceinformation);
141
-					}
142
-					else {
143
-						SLog::Write(LOGLEVEL_DEBUG, "Ignoring incoming device information as WIPE is due.");
144
-					}
145
-					if (!self::$decoder->getElementEndTag()) {  // SYNC_SETTINGS_SET
146
-						return false;
147
-					}
148
-					if (!self::$decoder->getElementEndTag()) {  // SYNC_SETTINGS_DEVICEINFORMATION
149
-						return false;
150
-					}
151
-					break;
152
-
153
-				default:
154
-					// TODO: a special status code needed?
155
-					SLog::Write(LOGLEVEL_WARN, sprintf("This property ('%s') is not allowed to be used in a provision request", $requestName));
156
-			}
157
-		}
158
-
159
-		if (!self::$decoder->getElementEndTag()) { // provision
160
-			return false;
161
-		}
162
-
163
-		if (PROVISIONING !== true) {
164
-			SLog::Write(LOGLEVEL_INFO, "No policies deployed to device");
165
-			$policystatus = SYNC_PROVISION_POLICYSTATUS_NOPOLICY;
166
-		}
167
-
168
-		self::$encoder->StartWBXML();
169
-
170
-		// just create a temporary key (i.e. iPhone OS4 Beta does not like policykey 0 in response)
171
-		$policykey = GSync::GetProvisioningManager()->GenerateProvisioningPolicyKey();
172
-
173
-		self::$encoder->startTag(SYNC_PROVISION_PROVISION);
174
-
175
-		self::$encoder->startTag(SYNC_PROVISION_STATUS);
176
-		self::$encoder->content($status);
177
-		self::$encoder->endTag();
178
-
179
-		if ($deviceInfoSet) {
180
-			self::$encoder->startTag(SYNC_SETTINGS_DEVICEINFORMATION);
181
-			self::$encoder->startTag(SYNC_SETTINGS_STATUS);
182
-			self::$encoder->content($deviceinformation->Status);
183
-			self::$encoder->endTag(); // SYNC_SETTINGS_STATUS
184
-				self::$encoder->endTag(); // SYNC_SETTINGS_DEVICEINFORMATION
185
-		}
186
-
187
-		self::$encoder->startTag(SYNC_PROVISION_POLICIES);
188
-		self::$encoder->startTag(SYNC_PROVISION_POLICY);
189
-
190
-		if (isset($policytype)) {
191
-			self::$encoder->startTag(SYNC_PROVISION_POLICYTYPE);
192
-			self::$encoder->content($policytype);
193
-			self::$encoder->endTag();
194
-		}
195
-
196
-		self::$encoder->startTag(SYNC_PROVISION_STATUS);
197
-		self::$encoder->content($policystatus);
198
-		self::$encoder->endTag();
199
-
200
-		self::$encoder->startTag(SYNC_PROVISION_POLICYKEY);
201
-		self::$encoder->content($policykey);
202
-		self::$encoder->endTag();
203
-
204
-		if ($phase2 && $policystatus === SYNC_PROVISION_POLICYSTATUS_SUCCESS) {
205
-			self::$encoder->startTag(SYNC_PROVISION_DATA);
206
-			if ($policytype == 'MS-WAP-Provisioning-XML') {
207
-				self::$encoder->content('<wap-provisioningdoc><characteristic type="SecurityPolicy"><parm name="4131" value="1"/><parm name="4133" value="1"/></characteristic></wap-provisioningdoc>');
208
-			}
209
-			elseif ($policytype == 'MS-EAS-Provisioning-WBXML') {
210
-				self::$encoder->startTag(SYNC_PROVISION_EASPROVISIONDOC);
211
-
212
-				// get the provisioning object and log the loaded policy values
213
-				$prov = GSync::GetProvisioningManager()->GetProvisioningObject(true);
214
-				if (!$prov->Check()) {
215
-					throw new FatalException("Invalid policies!");
216
-				}
217
-
218
-				GSync::GetProvisioningManager()->SavePolicyHash($prov);
219
-				$prov->Encode(self::$encoder);
220
-				self::$encoder->endTag();
221
-			}
222
-			else {
223
-				SLog::Write(LOGLEVEL_WARN, "Wrong policy type");
224
-				self::$topCollector->AnnounceInformation("Policytype not supported", true);
225
-
226
-				return false;
227
-			}
228
-			self::$topCollector->AnnounceInformation("Updated provisioning", true);
229
-
230
-			self::$encoder->endTag(); // data
231
-		}
232
-		self::$encoder->endTag(); // policy
233
-			self::$encoder->endTag(); // policies
234
-
235
-		// set the new final policy key in the provisioning manager
236
-		if (!$phase2 && !$wipeRequest) {
237
-			GSync::GetProvisioningManager()->SetProvisioningPolicyKey($policykey);
238
-			self::$topCollector->AnnounceInformation("Policies deployed", true);
239
-		}
240
-
241
-		// wipe data if a higher RWSTATUS is requested
242
-		if ($rwstatus > SYNC_PROVISION_RWSTATUS_OK && $policystatus === SYNC_PROVISION_POLICYSTATUS_SUCCESS) {
243
-			self::$encoder->startTag(SYNC_PROVISION_REMOTEWIPE, false, true);
244
-			GSync::GetProvisioningManager()->SetProvisioningWipeStatus(($rwstatusWiped) ? SYNC_PROVISION_RWSTATUS_WIPED : SYNC_PROVISION_RWSTATUS_REQUESTED);
245
-			self::$topCollector->AnnounceInformation(sprintf("Remote wipe %s", ($rwstatusWiped) ? "executed" : "requested"), true);
246
-		}
247
-
248
-		self::$encoder->endTag(); // provision
249
-
250
-		return true;
251
-	}
11
+    /**
12
+     * Handles the Provisioning command.
13
+     *
14
+     * @param int $commandCode
15
+     *
16
+     * @return bool
17
+     */
18
+    public function Handle($commandCode) {
19
+        $status = SYNC_PROVISION_STATUS_SUCCESS;
20
+        $policystatus = SYNC_PROVISION_POLICYSTATUS_SUCCESS;
21
+
22
+        $rwstatus = GSync::GetProvisioningManager()->GetProvisioningWipeStatus();
23
+        $rwstatusWiped = false;
24
+        $deviceInfoSet = false;
25
+        $wipeRequest = !($rwstatus < SYNC_PROVISION_RWSTATUS_PENDING);
26
+
27
+        // if this is a regular provisioning require that an authenticated remote user
28
+        if (!$wipeRequest) {
29
+            SLog::Write(LOGLEVEL_DEBUG, "RequestProcessor::HandleProvision(): Forcing delayed Authentication");
30
+            self::Authenticate();
31
+        }
32
+
33
+        $phase2 = true;
34
+
35
+        if (!self::$decoder->getElementStartTag(SYNC_PROVISION_PROVISION)) {
36
+            return false;
37
+        }
38
+
39
+        // Loop through Provision request tags. Possible are:
40
+        // - Remote Wipe
41
+        // - DeviceInformation
42
+        // - Policies
43
+        // Each of them should only be once per request.
44
+        WBXMLDecoder::ResetInWhile("provisioningMain");
45
+        while (WBXMLDecoder::InWhile("provisioningMain")) {
46
+            $requestName = "";
47
+            if (self::$decoder->getElementStartTag(SYNC_PROVISION_REMOTEWIPE)) {
48
+                $requestName = SYNC_PROVISION_REMOTEWIPE;
49
+            }
50
+            if (self::$decoder->getElementStartTag(SYNC_PROVISION_POLICIES)) {
51
+                $requestName = SYNC_PROVISION_POLICIES;
52
+            }
53
+            if (self::$decoder->getElementStartTag(SYNC_SETTINGS_DEVICEINFORMATION)) {
54
+                $requestName = SYNC_SETTINGS_DEVICEINFORMATION;
55
+            }
56
+
57
+            if (!$requestName) {
58
+                break;
59
+            }
60
+
61
+            // set is available for OOF, device password and device information
62
+            switch ($requestName) {
63
+                case SYNC_PROVISION_REMOTEWIPE:
64
+                    if (!self::$decoder->getElementStartTag(SYNC_PROVISION_STATUS)) {
65
+                        return false;
66
+                    }
67
+
68
+                    $instatus = self::$decoder->getElementContent();
69
+
70
+                    if (!self::$decoder->getElementEndTag()) {
71
+                        return false;
72
+                    }
73
+
74
+                    if (!self::$decoder->getElementEndTag()) {
75
+                        return false;
76
+                    }
77
+
78
+                    $phase2 = false;
79
+                    $rwstatusWiped = true;
80
+                    // TODO check - do it after while(1) finished?
81
+                    break;
82
+
83
+                case SYNC_PROVISION_POLICIES:
84
+                    if (!self::$decoder->getElementStartTag(SYNC_PROVISION_POLICY)) {
85
+                        return false;
86
+                    }
87
+
88
+                    if (!self::$decoder->getElementStartTag(SYNC_PROVISION_POLICYTYPE)) {
89
+                        return false;
90
+                    }
91
+
92
+                    $policytype = self::$decoder->getElementContent();
93
+                    if ($policytype != 'MS-WAP-Provisioning-XML' && $policytype != 'MS-EAS-Provisioning-WBXML') {
94
+                        $status = SYNC_PROVISION_STATUS_SERVERERROR;
95
+                    }
96
+                    if (!self::$decoder->getElementEndTag()) { // policytype
97
+                        return false;
98
+                    }
99
+
100
+                    if (self::$decoder->getElementStartTag(SYNC_PROVISION_POLICYKEY)) {
101
+                        $devpolicykey = self::$decoder->getElementContent();
102
+
103
+                        if (!self::$decoder->getElementEndTag()) {
104
+                            return false;
105
+                        }
106
+
107
+                        if (!self::$decoder->getElementStartTag(SYNC_PROVISION_STATUS)) {
108
+                            return false;
109
+                        }
110
+
111
+                        $instatus = self::$decoder->getElementContent();
112
+
113
+                        if (!self::$decoder->getElementEndTag()) {
114
+                            return false;
115
+                        }
116
+
117
+                        $phase2 = false;
118
+                    }
119
+
120
+                    if (!self::$decoder->getElementEndTag()) { // policy
121
+                        return false;
122
+                    }
123
+
124
+                    if (!self::$decoder->getElementEndTag()) { // policies
125
+                        return false;
126
+                    }
127
+                    break;
128
+
129
+                case SYNC_SETTINGS_DEVICEINFORMATION:
130
+                    // AS14.1 and later clients pass Device Information on the initial Provision request
131
+                    if (!self::$decoder->getElementStartTag(SYNC_SETTINGS_SET)) {
132
+                        return false;
133
+                    }
134
+                    $deviceInfoSet = true;
135
+                    $deviceinformation = new SyncDeviceInformation();
136
+                    $deviceinformation->Decode(self::$decoder);
137
+                    $deviceinformation->Status = SYNC_SETTINGSSTATUS_SUCCESS;
138
+                    if (!$wipeRequest) {
139
+                        // for this operation the device manager is available
140
+                        GSync::GetDeviceManager()->SaveDeviceInformation($deviceinformation);
141
+                    }
142
+                    else {
143
+                        SLog::Write(LOGLEVEL_DEBUG, "Ignoring incoming device information as WIPE is due.");
144
+                    }
145
+                    if (!self::$decoder->getElementEndTag()) {  // SYNC_SETTINGS_SET
146
+                        return false;
147
+                    }
148
+                    if (!self::$decoder->getElementEndTag()) {  // SYNC_SETTINGS_DEVICEINFORMATION
149
+                        return false;
150
+                    }
151
+                    break;
152
+
153
+                default:
154
+                    // TODO: a special status code needed?
155
+                    SLog::Write(LOGLEVEL_WARN, sprintf("This property ('%s') is not allowed to be used in a provision request", $requestName));
156
+            }
157
+        }
158
+
159
+        if (!self::$decoder->getElementEndTag()) { // provision
160
+            return false;
161
+        }
162
+
163
+        if (PROVISIONING !== true) {
164
+            SLog::Write(LOGLEVEL_INFO, "No policies deployed to device");
165
+            $policystatus = SYNC_PROVISION_POLICYSTATUS_NOPOLICY;
166
+        }
167
+
168
+        self::$encoder->StartWBXML();
169
+
170
+        // just create a temporary key (i.e. iPhone OS4 Beta does not like policykey 0 in response)
171
+        $policykey = GSync::GetProvisioningManager()->GenerateProvisioningPolicyKey();
172
+
173
+        self::$encoder->startTag(SYNC_PROVISION_PROVISION);
174
+
175
+        self::$encoder->startTag(SYNC_PROVISION_STATUS);
176
+        self::$encoder->content($status);
177
+        self::$encoder->endTag();
178
+
179
+        if ($deviceInfoSet) {
180
+            self::$encoder->startTag(SYNC_SETTINGS_DEVICEINFORMATION);
181
+            self::$encoder->startTag(SYNC_SETTINGS_STATUS);
182
+            self::$encoder->content($deviceinformation->Status);
183
+            self::$encoder->endTag(); // SYNC_SETTINGS_STATUS
184
+                self::$encoder->endTag(); // SYNC_SETTINGS_DEVICEINFORMATION
185
+        }
186
+
187
+        self::$encoder->startTag(SYNC_PROVISION_POLICIES);
188
+        self::$encoder->startTag(SYNC_PROVISION_POLICY);
189
+
190
+        if (isset($policytype)) {
191
+            self::$encoder->startTag(SYNC_PROVISION_POLICYTYPE);
192
+            self::$encoder->content($policytype);
193
+            self::$encoder->endTag();
194
+        }
195
+
196
+        self::$encoder->startTag(SYNC_PROVISION_STATUS);
197
+        self::$encoder->content($policystatus);
198
+        self::$encoder->endTag();
199
+
200
+        self::$encoder->startTag(SYNC_PROVISION_POLICYKEY);
201
+        self::$encoder->content($policykey);
202
+        self::$encoder->endTag();
203
+
204
+        if ($phase2 && $policystatus === SYNC_PROVISION_POLICYSTATUS_SUCCESS) {
205
+            self::$encoder->startTag(SYNC_PROVISION_DATA);
206
+            if ($policytype == 'MS-WAP-Provisioning-XML') {
207
+                self::$encoder->content('<wap-provisioningdoc><characteristic type="SecurityPolicy"><parm name="4131" value="1"/><parm name="4133" value="1"/></characteristic></wap-provisioningdoc>');
208
+            }
209
+            elseif ($policytype == 'MS-EAS-Provisioning-WBXML') {
210
+                self::$encoder->startTag(SYNC_PROVISION_EASPROVISIONDOC);
211
+
212
+                // get the provisioning object and log the loaded policy values
213
+                $prov = GSync::GetProvisioningManager()->GetProvisioningObject(true);
214
+                if (!$prov->Check()) {
215
+                    throw new FatalException("Invalid policies!");
216
+                }
217
+
218
+                GSync::GetProvisioningManager()->SavePolicyHash($prov);
219
+                $prov->Encode(self::$encoder);
220
+                self::$encoder->endTag();
221
+            }
222
+            else {
223
+                SLog::Write(LOGLEVEL_WARN, "Wrong policy type");
224
+                self::$topCollector->AnnounceInformation("Policytype not supported", true);
225
+
226
+                return false;
227
+            }
228
+            self::$topCollector->AnnounceInformation("Updated provisioning", true);
229
+
230
+            self::$encoder->endTag(); // data
231
+        }
232
+        self::$encoder->endTag(); // policy
233
+            self::$encoder->endTag(); // policies
234
+
235
+        // set the new final policy key in the provisioning manager
236
+        if (!$phase2 && !$wipeRequest) {
237
+            GSync::GetProvisioningManager()->SetProvisioningPolicyKey($policykey);
238
+            self::$topCollector->AnnounceInformation("Policies deployed", true);
239
+        }
240
+
241
+        // wipe data if a higher RWSTATUS is requested
242
+        if ($rwstatus > SYNC_PROVISION_RWSTATUS_OK && $policystatus === SYNC_PROVISION_POLICYSTATUS_SUCCESS) {
243
+            self::$encoder->startTag(SYNC_PROVISION_REMOTEWIPE, false, true);
244
+            GSync::GetProvisioningManager()->SetProvisioningWipeStatus(($rwstatusWiped) ? SYNC_PROVISION_RWSTATUS_WIPED : SYNC_PROVISION_RWSTATUS_REQUESTED);
245
+            self::$topCollector->AnnounceInformation(sprintf("Remote wipe %s", ($rwstatusWiped) ? "executed" : "requested"), true);
246
+        }
247
+
248
+        self::$encoder->endTag(); // provision
249
+
250
+        return true;
251
+    }
252 252
 }
Please login to merge, or discard this patch.
Braces   +3 added lines, -6 removed lines patch added patch discarded remove patch
@@ -138,8 +138,7 @@  discard block
 block discarded – undo
138 138
 					if (!$wipeRequest) {
139 139
 						// for this operation the device manager is available
140 140
 						GSync::GetDeviceManager()->SaveDeviceInformation($deviceinformation);
141
-					}
142
-					else {
141
+					} else {
143 142
 						SLog::Write(LOGLEVEL_DEBUG, "Ignoring incoming device information as WIPE is due.");
144 143
 					}
145 144
 					if (!self::$decoder->getElementEndTag()) {  // SYNC_SETTINGS_SET
@@ -205,8 +204,7 @@  discard block
 block discarded – undo
205 204
 			self::$encoder->startTag(SYNC_PROVISION_DATA);
206 205
 			if ($policytype == 'MS-WAP-Provisioning-XML') {
207 206
 				self::$encoder->content('<wap-provisioningdoc><characteristic type="SecurityPolicy"><parm name="4131" value="1"/><parm name="4133" value="1"/></characteristic></wap-provisioningdoc>');
208
-			}
209
-			elseif ($policytype == 'MS-EAS-Provisioning-WBXML') {
207
+			} elseif ($policytype == 'MS-EAS-Provisioning-WBXML') {
210 208
 				self::$encoder->startTag(SYNC_PROVISION_EASPROVISIONDOC);
211 209
 
212 210
 				// get the provisioning object and log the loaded policy values
@@ -218,8 +216,7 @@  discard block
 block discarded – undo
218 216
 				GSync::GetProvisioningManager()->SavePolicyHash($prov);
219 217
 				$prov->Encode(self::$encoder);
220 218
 				self::$encoder->endTag();
221
-			}
222
-			else {
219
+			} else {
223 220
 				SLog::Write(LOGLEVEL_WARN, "Wrong policy type");
224 221
 				self::$topCollector->AnnounceInformation("Policytype not supported", true);
225 222
 
Please login to merge, or discard this patch.
lib/request/request.php 3 patches
Indentation   +782 added lines, -782 removed lines patch added patch discarded remove patch
@@ -8,776 +8,776 @@  discard block
 block discarded – undo
8 8
  */
9 9
 
10 10
 class Request {
11
-	public const MAXMEMORYUSAGE = 0.9;     // use max. 90% of allowed memory when syncing
12
-	public const UNKNOWN = "unknown";
13
-	public const IMPERSONATE_DELIM = '#';
14
-
15
-	/**
16
-	 * self::filterEvilInput() options.
17
-	 */
18
-	public const LETTERS_ONLY = 1;
19
-	public const HEX_ONLY = 2;
20
-	public const WORDCHAR_ONLY = 3;
21
-	public const NUMBERS_ONLY = 4;
22
-	public const NUMBERSDOT_ONLY = 5;
23
-	public const HEX_EXTENDED = 6;
24
-	public const ISO8601 = 7;
25
-	public const HEX_EXTENDED2 = 8;
26
-
27
-	/**
28
-	 * Command parameters for base64 encoded requests (AS >= 12.1).
29
-	 */
30
-	public const COMMANDPARAM_ATTACHMENTNAME = 0;
31
-	public const COMMANDPARAM_COLLECTIONID = 1; // deprecated
32
-	public const COMMANDPARAM_COLLECTIONNAME = 2; // deprecated
33
-	public const COMMANDPARAM_ITEMID = 3;
34
-	public const COMMANDPARAM_LONGID = 4;
35
-	public const COMMANDPARAM_PARENTID = 5; // deprecated
36
-	public const COMMANDPARAM_OCCURRENCE = 6;
37
-	public const COMMANDPARAM_OPTIONS = 7; // used by SmartReply, SmartForward, SendMail, ItemOperations
38
-	public const COMMANDPARAM_USER = 8; // used by any command
39
-	// possible bitflags for COMMANDPARAM_OPTIONS
40
-	public const COMMANDPARAM_OPTIONS_SAVEINSENT = 0x01;
41
-	public const COMMANDPARAM_OPTIONS_ACCEPTMULTIPART = 0x02;
42
-
43
-	private static $input;
44
-	private static $output;
45
-	private static $headers;
46
-	private static $command;
47
-	private static $method;
48
-	private static $remoteAddr;
49
-	private static $getUser;
50
-	private static $devid;
51
-	private static $devtype;
52
-	private static $authUserString;
53
-	private static $authUser;
54
-	private static $authDomain;
55
-	private static $authPassword;
56
-	private static $impersonatedUser;
57
-	private static $asProtocolVersion;
58
-	private static $policykey;
59
-	private static $useragent;
60
-	private static $attachmentName;
61
-	private static $collectionId;
62
-	private static $itemId;
63
-	private static $longId; // TODO
64
-	private static $occurrence; // TODO
65
-	private static $saveInSent;
66
-	private static $acceptMultipart;
67
-	private static $base64QueryDecoded;
68
-	private static $expectedConnectionTimeout;
69
-	private static $memoryLimit;
70
-
71
-	/**
72
-	 * Initializes request data.
73
-	 *
74
-	 * @return
75
-	 */
76
-	public static function Initialize() {
77
-		// try to open stdin & stdout
78
-		self::$input = fopen("php://input", "r");
79
-		self::$output = fopen("php://output", "w+");
80
-
81
-		// Parse the standard GET parameters
82
-		if (isset($_GET["Cmd"])) {
83
-			self::$command = self::filterEvilInput($_GET["Cmd"], self::LETTERS_ONLY);
84
-		}
85
-
86
-		// getUser is unfiltered, as everything is allowed.. even "/", "\" or ".."
87
-		if (isset($_GET["User"])) {
88
-			self::$getUser = strtolower($_GET["User"]);
89
-			if (defined('USE_FULLEMAIL_FOR_LOGIN') && !USE_FULLEMAIL_FOR_LOGIN) {
90
-				self::$getUser = Utils::GetLocalPartFromEmail(self::$getUser);
91
-			}
92
-		}
93
-		if (isset($_GET["DeviceId"])) {
94
-			self::$devid = strtolower(self::filterEvilInput($_GET["DeviceId"], self::WORDCHAR_ONLY));
95
-		}
96
-		if (isset($_GET["DeviceType"])) {
97
-			self::$devtype = self::filterEvilInput($_GET["DeviceType"], self::LETTERS_ONLY);
98
-		}
99
-		if (isset($_GET["AttachmentName"])) {
100
-			self::$attachmentName = self::filterEvilInput($_GET["AttachmentName"], self::HEX_EXTENDED2);
101
-		}
102
-		if (isset($_GET["CollectionId"])) {
103
-			self::$collectionId = self::filterEvilInput($_GET["CollectionId"], self::HEX_EXTENDED2);
104
-		}
105
-		if (isset($_GET["ItemId"])) {
106
-			self::$itemId = self::filterEvilInput($_GET["ItemId"], self::HEX_EXTENDED2);
107
-		}
108
-		if (isset($_GET["SaveInSent"]) && $_GET["SaveInSent"] == "T") {
109
-			self::$saveInSent = true;
110
-		}
111
-
112
-		if (isset($_SERVER["REQUEST_METHOD"])) {
113
-			self::$method = self::filterEvilInput($_SERVER["REQUEST_METHOD"], self::LETTERS_ONLY);
114
-		}
115
-		// TODO check IPv6 addresses
116
-		if (isset($_SERVER["REMOTE_ADDR"])) {
117
-			self::$remoteAddr = self::filterIP($_SERVER["REMOTE_ADDR"]);
118
-		}
119
-
120
-		// in protocol version > 14 mobile send these inputs as encoded query string
121
-		if (!isset(self::$command) && !empty($_SERVER['QUERY_STRING']) && Utils::IsBase64String($_SERVER['QUERY_STRING'])) {
122
-			self::decodeBase64URI();
123
-			if (!isset(self::$command) && isset(self::$base64QueryDecoded['Command'])) {
124
-				self::$command = Utils::GetCommandFromCode(self::$base64QueryDecoded['Command']);
125
-			}
126
-
127
-			if (!isset(self::$getUser) && isset(self::$base64QueryDecoded[self::COMMANDPARAM_USER])) {
128
-				self::$getUser = strtolower(self::$base64QueryDecoded[self::COMMANDPARAM_USER]);
129
-				if (defined('USE_FULLEMAIL_FOR_LOGIN') && !USE_FULLEMAIL_FOR_LOGIN) {
130
-					self::$getUser = Utils::GetLocalPartFromEmail(self::$getUser);
131
-				}
132
-			}
133
-
134
-			if (!isset(self::$devid) && isset(self::$base64QueryDecoded['DevID'])) {
135
-				self::$devid = strtolower(self::filterEvilInput(self::$base64QueryDecoded['DevID'], self::WORDCHAR_ONLY));
136
-			}
137
-
138
-			if (!isset(self::$devtype) && isset(self::$base64QueryDecoded['DevType'])) {
139
-				self::$devtype = self::filterEvilInput(self::$base64QueryDecoded['DevType'], self::LETTERS_ONLY);
140
-			}
141
-
142
-			if (isset(self::$base64QueryDecoded['PolKey'])) {
143
-				self::$policykey = (int) self::filterEvilInput(self::$base64QueryDecoded['PolKey'], self::NUMBERS_ONLY);
144
-			}
145
-
146
-			if (isset(self::$base64QueryDecoded['ProtVer'])) {
147
-				self::$asProtocolVersion = self::filterEvilInput(self::$base64QueryDecoded['ProtVer'], self::NUMBERS_ONLY) / 10;
148
-			}
149
-
150
-			if (isset(self::$base64QueryDecoded[self::COMMANDPARAM_ATTACHMENTNAME])) {
151
-				self::$attachmentName = self::filterEvilInput(self::$base64QueryDecoded[self::COMMANDPARAM_ATTACHMENTNAME], self::HEX_EXTENDED2);
152
-			}
153
-
154
-			if (isset(self::$base64QueryDecoded[self::COMMANDPARAM_COLLECTIONID])) {
155
-				self::$collectionId = self::filterEvilInput(self::$base64QueryDecoded[self::COMMANDPARAM_COLLECTIONID], self::HEX_EXTENDED2);
156
-			}
157
-
158
-			if (isset(self::$base64QueryDecoded[self::COMMANDPARAM_ITEMID])) {
159
-				self::$itemId = self::filterEvilInput(self::$base64QueryDecoded[self::COMMANDPARAM_ITEMID], self::HEX_EXTENDED2);
160
-			}
161
-
162
-			if (isset(self::$base64QueryDecoded[self::COMMANDPARAM_OPTIONS]) && (ord(self::$base64QueryDecoded[self::COMMANDPARAM_OPTIONS]) & self::COMMANDPARAM_OPTIONS_SAVEINSENT)) {
163
-				self::$saveInSent = true;
164
-			}
165
-
166
-			if (isset(self::$base64QueryDecoded[self::COMMANDPARAM_OPTIONS]) && (ord(self::$base64QueryDecoded[self::COMMANDPARAM_OPTIONS]) & self::COMMANDPARAM_OPTIONS_ACCEPTMULTIPART)) {
167
-				self::$acceptMultipart = true;
168
-			}
169
-		}
170
-
171
-		// in base64 encoded query string user is not necessarily set
172
-		if (!isset(self::$getUser) && isset($_SERVER['PHP_AUTH_USER'])) {
173
-			list(self::$getUser) = Utils::SplitDomainUser(strtolower($_SERVER['PHP_AUTH_USER']));
174
-			if (defined('USE_FULLEMAIL_FOR_LOGIN') && !USE_FULLEMAIL_FOR_LOGIN) {
175
-				self::$getUser = Utils::GetLocalPartFromEmail(self::$getUser);
176
-			}
177
-		}
178
-
179
-		// authUser & authPassword are unfiltered!
180
-		// split username & domain if received as one
181
-		if (isset($_SERVER['PHP_AUTH_USER'])) {
182
-			list(self::$authUserString, self::$authDomain) = Utils::SplitDomainUser($_SERVER['PHP_AUTH_USER']);
183
-			self::$authPassword = (isset($_SERVER['PHP_AUTH_PW'])) ? $_SERVER['PHP_AUTH_PW'] : "";
184
-		}
185
-
186
-		// process impersonation
187
-		self::$authUser = self::$authUserString;
188
-
189
-		if (defined('USE_FULLEMAIL_FOR_LOGIN') && !USE_FULLEMAIL_FOR_LOGIN) {
190
-			self::$authUser = Utils::GetLocalPartFromEmail(self::$authUser);
191
-		}
192
-
193
-		// get & convert configured memory limit
194
-		$memoryLimit = ini_get('memory_limit');
195
-		if ($memoryLimit == -1) {
196
-			self::$memoryLimit = false;
197
-		}
198
-		else {
199
-			preg_replace_callback(
200
-				'/(\-?\d+)(.?)/',
201
-				function ($m) {
202
-					self::$memoryLimit = $m[1] * pow(1024, strpos('BKMG', $m[2])) * self::MAXMEMORYUSAGE;
203
-				},
204
-				strtoupper($memoryLimit)
205
-			);
206
-		}
207
-	}
208
-
209
-	/**
210
-	 * Reads and processes the request headers.
211
-	 *
212
-	 * @return
213
-	 */
214
-	public static function ProcessHeaders() {
215
-		self::$headers = array_change_key_case(apache_request_headers(), CASE_LOWER);
216
-		self::$useragent = (isset(self::$headers["user-agent"])) ? self::$headers["user-agent"] : self::UNKNOWN;
217
-		if (!isset(self::$asProtocolVersion)) {
218
-			self::$asProtocolVersion = (isset(self::$headers["ms-asprotocolversion"])) ? self::filterEvilInput(self::$headers["ms-asprotocolversion"], self::NUMBERSDOT_ONLY) : GSync::GetLatestSupportedASVersion();
219
-		}
220
-
221
-		// if policykey is not yet set, try to set it from the header
222
-		// the policy key might be set in Request::Initialize from the base64 encoded query
223
-		if (!isset(self::$policykey)) {
224
-			if (isset(self::$headers["x-ms-policykey"])) {
225
-				self::$policykey = (int) self::filterEvilInput(self::$headers["x-ms-policykey"], self::NUMBERS_ONLY);
226
-			}
227
-			else {
228
-				self::$policykey = 0;
229
-			}
230
-		}
231
-
232
-		if (isset(self::$base64QueryDecoded)) {
233
-			SLog::Write(LOGLEVEL_DEBUG, sprintf("Request::ProcessHeaders(): base64 query string: '%s' (decoded: '%s')", $_SERVER['QUERY_STRING'], http_build_query(self::$base64QueryDecoded, '', ',')));
234
-			if (isset(self::$policykey)) {
235
-				self::$headers["x-ms-policykey"] = self::$policykey;
236
-			}
237
-
238
-			if (isset(self::$asProtocolVersion)) {
239
-				self::$headers["ms-asprotocolversion"] = self::$asProtocolVersion;
240
-			}
241
-		}
242
-
243
-		if (!isset(self::$acceptMultipart) && isset(self::$headers["ms-asacceptmultipart"]) && strtoupper(self::$headers["ms-asacceptmultipart"]) == "T") {
244
-			self::$acceptMultipart = true;
245
-		}
246
-
247
-		SLog::Write(LOGLEVEL_DEBUG, sprintf("Request::ProcessHeaders() ASVersion: %s", self::$asProtocolVersion));
248
-
249
-		if (defined('USE_CUSTOM_REMOTE_IP_HEADER') && USE_CUSTOM_REMOTE_IP_HEADER !== false) {
250
-			// make custom header compatible with Apache modphp (see ZP-1332)
251
-			$header = $apacheHeader = strtolower(USE_CUSTOM_REMOTE_IP_HEADER);
252
-			if (substr($apacheHeader, 0, 5) === 'http_') {
253
-				$apacheHeader = substr($apacheHeader, 5);
254
-			}
255
-			$apacheHeader = str_replace("_", "-", $apacheHeader);
256
-			if (isset(self::$headers[$header]) || isset(self::$headers[$apacheHeader])) {
257
-				$remoteIP = isset(self::$headers[$header]) ? self::$headers[$header] : self::$headers[$apacheHeader];
258
-				// X-Forwarded-For may contain multiple IPs separated by comma: client, proxy1, proxy2.
259
-				// In such case we will only check the client IP. See https://jira.z-hub.io/browse/ZP-1434.
260
-				if (strpos($remoteIP, ',') !== false) {
261
-					$remoteIP = trim(explode(',', $remoteIP)[0]);
262
-				}
263
-				$remoteIP = self::filterIP($remoteIP);
264
-				if ($remoteIP) {
265
-					SLog::Write(LOGLEVEL_DEBUG, sprintf("Using custom header '%s' to determine remote IP: %s - connect is coming from IP: %s", USE_CUSTOM_REMOTE_IP_HEADER, $remoteIP, self::$remoteAddr));
266
-					self::$remoteAddr = $remoteIP;
267
-				}
268
-			}
269
-		}
270
-	}
271
-
272
-	/**
273
-	 * @return bool data sent or not
274
-	 */
275
-	public static function HasAuthenticationInfo() {
276
-		return self::$authUser != "" && self::$authPassword != "";
277
-	}
278
-
279
-	/*----------------------------------------------------------------------------------------------------------
11
+    public const MAXMEMORYUSAGE = 0.9;     // use max. 90% of allowed memory when syncing
12
+    public const UNKNOWN = "unknown";
13
+    public const IMPERSONATE_DELIM = '#';
14
+
15
+    /**
16
+     * self::filterEvilInput() options.
17
+     */
18
+    public const LETTERS_ONLY = 1;
19
+    public const HEX_ONLY = 2;
20
+    public const WORDCHAR_ONLY = 3;
21
+    public const NUMBERS_ONLY = 4;
22
+    public const NUMBERSDOT_ONLY = 5;
23
+    public const HEX_EXTENDED = 6;
24
+    public const ISO8601 = 7;
25
+    public const HEX_EXTENDED2 = 8;
26
+
27
+    /**
28
+     * Command parameters for base64 encoded requests (AS >= 12.1).
29
+     */
30
+    public const COMMANDPARAM_ATTACHMENTNAME = 0;
31
+    public const COMMANDPARAM_COLLECTIONID = 1; // deprecated
32
+    public const COMMANDPARAM_COLLECTIONNAME = 2; // deprecated
33
+    public const COMMANDPARAM_ITEMID = 3;
34
+    public const COMMANDPARAM_LONGID = 4;
35
+    public const COMMANDPARAM_PARENTID = 5; // deprecated
36
+    public const COMMANDPARAM_OCCURRENCE = 6;
37
+    public const COMMANDPARAM_OPTIONS = 7; // used by SmartReply, SmartForward, SendMail, ItemOperations
38
+    public const COMMANDPARAM_USER = 8; // used by any command
39
+    // possible bitflags for COMMANDPARAM_OPTIONS
40
+    public const COMMANDPARAM_OPTIONS_SAVEINSENT = 0x01;
41
+    public const COMMANDPARAM_OPTIONS_ACCEPTMULTIPART = 0x02;
42
+
43
+    private static $input;
44
+    private static $output;
45
+    private static $headers;
46
+    private static $command;
47
+    private static $method;
48
+    private static $remoteAddr;
49
+    private static $getUser;
50
+    private static $devid;
51
+    private static $devtype;
52
+    private static $authUserString;
53
+    private static $authUser;
54
+    private static $authDomain;
55
+    private static $authPassword;
56
+    private static $impersonatedUser;
57
+    private static $asProtocolVersion;
58
+    private static $policykey;
59
+    private static $useragent;
60
+    private static $attachmentName;
61
+    private static $collectionId;
62
+    private static $itemId;
63
+    private static $longId; // TODO
64
+    private static $occurrence; // TODO
65
+    private static $saveInSent;
66
+    private static $acceptMultipart;
67
+    private static $base64QueryDecoded;
68
+    private static $expectedConnectionTimeout;
69
+    private static $memoryLimit;
70
+
71
+    /**
72
+     * Initializes request data.
73
+     *
74
+     * @return
75
+     */
76
+    public static function Initialize() {
77
+        // try to open stdin & stdout
78
+        self::$input = fopen("php://input", "r");
79
+        self::$output = fopen("php://output", "w+");
80
+
81
+        // Parse the standard GET parameters
82
+        if (isset($_GET["Cmd"])) {
83
+            self::$command = self::filterEvilInput($_GET["Cmd"], self::LETTERS_ONLY);
84
+        }
85
+
86
+        // getUser is unfiltered, as everything is allowed.. even "/", "\" or ".."
87
+        if (isset($_GET["User"])) {
88
+            self::$getUser = strtolower($_GET["User"]);
89
+            if (defined('USE_FULLEMAIL_FOR_LOGIN') && !USE_FULLEMAIL_FOR_LOGIN) {
90
+                self::$getUser = Utils::GetLocalPartFromEmail(self::$getUser);
91
+            }
92
+        }
93
+        if (isset($_GET["DeviceId"])) {
94
+            self::$devid = strtolower(self::filterEvilInput($_GET["DeviceId"], self::WORDCHAR_ONLY));
95
+        }
96
+        if (isset($_GET["DeviceType"])) {
97
+            self::$devtype = self::filterEvilInput($_GET["DeviceType"], self::LETTERS_ONLY);
98
+        }
99
+        if (isset($_GET["AttachmentName"])) {
100
+            self::$attachmentName = self::filterEvilInput($_GET["AttachmentName"], self::HEX_EXTENDED2);
101
+        }
102
+        if (isset($_GET["CollectionId"])) {
103
+            self::$collectionId = self::filterEvilInput($_GET["CollectionId"], self::HEX_EXTENDED2);
104
+        }
105
+        if (isset($_GET["ItemId"])) {
106
+            self::$itemId = self::filterEvilInput($_GET["ItemId"], self::HEX_EXTENDED2);
107
+        }
108
+        if (isset($_GET["SaveInSent"]) && $_GET["SaveInSent"] == "T") {
109
+            self::$saveInSent = true;
110
+        }
111
+
112
+        if (isset($_SERVER["REQUEST_METHOD"])) {
113
+            self::$method = self::filterEvilInput($_SERVER["REQUEST_METHOD"], self::LETTERS_ONLY);
114
+        }
115
+        // TODO check IPv6 addresses
116
+        if (isset($_SERVER["REMOTE_ADDR"])) {
117
+            self::$remoteAddr = self::filterIP($_SERVER["REMOTE_ADDR"]);
118
+        }
119
+
120
+        // in protocol version > 14 mobile send these inputs as encoded query string
121
+        if (!isset(self::$command) && !empty($_SERVER['QUERY_STRING']) && Utils::IsBase64String($_SERVER['QUERY_STRING'])) {
122
+            self::decodeBase64URI();
123
+            if (!isset(self::$command) && isset(self::$base64QueryDecoded['Command'])) {
124
+                self::$command = Utils::GetCommandFromCode(self::$base64QueryDecoded['Command']);
125
+            }
126
+
127
+            if (!isset(self::$getUser) && isset(self::$base64QueryDecoded[self::COMMANDPARAM_USER])) {
128
+                self::$getUser = strtolower(self::$base64QueryDecoded[self::COMMANDPARAM_USER]);
129
+                if (defined('USE_FULLEMAIL_FOR_LOGIN') && !USE_FULLEMAIL_FOR_LOGIN) {
130
+                    self::$getUser = Utils::GetLocalPartFromEmail(self::$getUser);
131
+                }
132
+            }
133
+
134
+            if (!isset(self::$devid) && isset(self::$base64QueryDecoded['DevID'])) {
135
+                self::$devid = strtolower(self::filterEvilInput(self::$base64QueryDecoded['DevID'], self::WORDCHAR_ONLY));
136
+            }
137
+
138
+            if (!isset(self::$devtype) && isset(self::$base64QueryDecoded['DevType'])) {
139
+                self::$devtype = self::filterEvilInput(self::$base64QueryDecoded['DevType'], self::LETTERS_ONLY);
140
+            }
141
+
142
+            if (isset(self::$base64QueryDecoded['PolKey'])) {
143
+                self::$policykey = (int) self::filterEvilInput(self::$base64QueryDecoded['PolKey'], self::NUMBERS_ONLY);
144
+            }
145
+
146
+            if (isset(self::$base64QueryDecoded['ProtVer'])) {
147
+                self::$asProtocolVersion = self::filterEvilInput(self::$base64QueryDecoded['ProtVer'], self::NUMBERS_ONLY) / 10;
148
+            }
149
+
150
+            if (isset(self::$base64QueryDecoded[self::COMMANDPARAM_ATTACHMENTNAME])) {
151
+                self::$attachmentName = self::filterEvilInput(self::$base64QueryDecoded[self::COMMANDPARAM_ATTACHMENTNAME], self::HEX_EXTENDED2);
152
+            }
153
+
154
+            if (isset(self::$base64QueryDecoded[self::COMMANDPARAM_COLLECTIONID])) {
155
+                self::$collectionId = self::filterEvilInput(self::$base64QueryDecoded[self::COMMANDPARAM_COLLECTIONID], self::HEX_EXTENDED2);
156
+            }
157
+
158
+            if (isset(self::$base64QueryDecoded[self::COMMANDPARAM_ITEMID])) {
159
+                self::$itemId = self::filterEvilInput(self::$base64QueryDecoded[self::COMMANDPARAM_ITEMID], self::HEX_EXTENDED2);
160
+            }
161
+
162
+            if (isset(self::$base64QueryDecoded[self::COMMANDPARAM_OPTIONS]) && (ord(self::$base64QueryDecoded[self::COMMANDPARAM_OPTIONS]) & self::COMMANDPARAM_OPTIONS_SAVEINSENT)) {
163
+                self::$saveInSent = true;
164
+            }
165
+
166
+            if (isset(self::$base64QueryDecoded[self::COMMANDPARAM_OPTIONS]) && (ord(self::$base64QueryDecoded[self::COMMANDPARAM_OPTIONS]) & self::COMMANDPARAM_OPTIONS_ACCEPTMULTIPART)) {
167
+                self::$acceptMultipart = true;
168
+            }
169
+        }
170
+
171
+        // in base64 encoded query string user is not necessarily set
172
+        if (!isset(self::$getUser) && isset($_SERVER['PHP_AUTH_USER'])) {
173
+            list(self::$getUser) = Utils::SplitDomainUser(strtolower($_SERVER['PHP_AUTH_USER']));
174
+            if (defined('USE_FULLEMAIL_FOR_LOGIN') && !USE_FULLEMAIL_FOR_LOGIN) {
175
+                self::$getUser = Utils::GetLocalPartFromEmail(self::$getUser);
176
+            }
177
+        }
178
+
179
+        // authUser & authPassword are unfiltered!
180
+        // split username & domain if received as one
181
+        if (isset($_SERVER['PHP_AUTH_USER'])) {
182
+            list(self::$authUserString, self::$authDomain) = Utils::SplitDomainUser($_SERVER['PHP_AUTH_USER']);
183
+            self::$authPassword = (isset($_SERVER['PHP_AUTH_PW'])) ? $_SERVER['PHP_AUTH_PW'] : "";
184
+        }
185
+
186
+        // process impersonation
187
+        self::$authUser = self::$authUserString;
188
+
189
+        if (defined('USE_FULLEMAIL_FOR_LOGIN') && !USE_FULLEMAIL_FOR_LOGIN) {
190
+            self::$authUser = Utils::GetLocalPartFromEmail(self::$authUser);
191
+        }
192
+
193
+        // get & convert configured memory limit
194
+        $memoryLimit = ini_get('memory_limit');
195
+        if ($memoryLimit == -1) {
196
+            self::$memoryLimit = false;
197
+        }
198
+        else {
199
+            preg_replace_callback(
200
+                '/(\-?\d+)(.?)/',
201
+                function ($m) {
202
+                    self::$memoryLimit = $m[1] * pow(1024, strpos('BKMG', $m[2])) * self::MAXMEMORYUSAGE;
203
+                },
204
+                strtoupper($memoryLimit)
205
+            );
206
+        }
207
+    }
208
+
209
+    /**
210
+     * Reads and processes the request headers.
211
+     *
212
+     * @return
213
+     */
214
+    public static function ProcessHeaders() {
215
+        self::$headers = array_change_key_case(apache_request_headers(), CASE_LOWER);
216
+        self::$useragent = (isset(self::$headers["user-agent"])) ? self::$headers["user-agent"] : self::UNKNOWN;
217
+        if (!isset(self::$asProtocolVersion)) {
218
+            self::$asProtocolVersion = (isset(self::$headers["ms-asprotocolversion"])) ? self::filterEvilInput(self::$headers["ms-asprotocolversion"], self::NUMBERSDOT_ONLY) : GSync::GetLatestSupportedASVersion();
219
+        }
220
+
221
+        // if policykey is not yet set, try to set it from the header
222
+        // the policy key might be set in Request::Initialize from the base64 encoded query
223
+        if (!isset(self::$policykey)) {
224
+            if (isset(self::$headers["x-ms-policykey"])) {
225
+                self::$policykey = (int) self::filterEvilInput(self::$headers["x-ms-policykey"], self::NUMBERS_ONLY);
226
+            }
227
+            else {
228
+                self::$policykey = 0;
229
+            }
230
+        }
231
+
232
+        if (isset(self::$base64QueryDecoded)) {
233
+            SLog::Write(LOGLEVEL_DEBUG, sprintf("Request::ProcessHeaders(): base64 query string: '%s' (decoded: '%s')", $_SERVER['QUERY_STRING'], http_build_query(self::$base64QueryDecoded, '', ',')));
234
+            if (isset(self::$policykey)) {
235
+                self::$headers["x-ms-policykey"] = self::$policykey;
236
+            }
237
+
238
+            if (isset(self::$asProtocolVersion)) {
239
+                self::$headers["ms-asprotocolversion"] = self::$asProtocolVersion;
240
+            }
241
+        }
242
+
243
+        if (!isset(self::$acceptMultipart) && isset(self::$headers["ms-asacceptmultipart"]) && strtoupper(self::$headers["ms-asacceptmultipart"]) == "T") {
244
+            self::$acceptMultipart = true;
245
+        }
246
+
247
+        SLog::Write(LOGLEVEL_DEBUG, sprintf("Request::ProcessHeaders() ASVersion: %s", self::$asProtocolVersion));
248
+
249
+        if (defined('USE_CUSTOM_REMOTE_IP_HEADER') && USE_CUSTOM_REMOTE_IP_HEADER !== false) {
250
+            // make custom header compatible with Apache modphp (see ZP-1332)
251
+            $header = $apacheHeader = strtolower(USE_CUSTOM_REMOTE_IP_HEADER);
252
+            if (substr($apacheHeader, 0, 5) === 'http_') {
253
+                $apacheHeader = substr($apacheHeader, 5);
254
+            }
255
+            $apacheHeader = str_replace("_", "-", $apacheHeader);
256
+            if (isset(self::$headers[$header]) || isset(self::$headers[$apacheHeader])) {
257
+                $remoteIP = isset(self::$headers[$header]) ? self::$headers[$header] : self::$headers[$apacheHeader];
258
+                // X-Forwarded-For may contain multiple IPs separated by comma: client, proxy1, proxy2.
259
+                // In such case we will only check the client IP. See https://jira.z-hub.io/browse/ZP-1434.
260
+                if (strpos($remoteIP, ',') !== false) {
261
+                    $remoteIP = trim(explode(',', $remoteIP)[0]);
262
+                }
263
+                $remoteIP = self::filterIP($remoteIP);
264
+                if ($remoteIP) {
265
+                    SLog::Write(LOGLEVEL_DEBUG, sprintf("Using custom header '%s' to determine remote IP: %s - connect is coming from IP: %s", USE_CUSTOM_REMOTE_IP_HEADER, $remoteIP, self::$remoteAddr));
266
+                    self::$remoteAddr = $remoteIP;
267
+                }
268
+            }
269
+        }
270
+    }
271
+
272
+    /**
273
+     * @return bool data sent or not
274
+     */
275
+    public static function HasAuthenticationInfo() {
276
+        return self::$authUser != "" && self::$authPassword != "";
277
+    }
278
+
279
+    /*----------------------------------------------------------------------------------------------------------
280 280
 	 * Getter & Checker
281 281
 	 */
282 282
 
283
-	/**
284
-	 * Returns the input stream.
285
-	 *
286
-	 * @return handle/boolean      false if not available
287
-	 */
288
-	public static function GetInputStream() {
289
-		if (isset(self::$input)) {
290
-			return self::$input;
291
-		}
292
-
293
-		return false;
294
-	}
295
-
296
-	/**
297
-	 * Returns the output stream.
298
-	 *
299
-	 * @return handle/boolean      false if not available
300
-	 */
301
-	public static function GetOutputStream() {
302
-		if (isset(self::$output)) {
303
-			return self::$output;
304
-		}
305
-
306
-		return false;
307
-	}
308
-
309
-	/**
310
-	 * Returns the request method.
311
-	 *
312
-	 * @return string
313
-	 */
314
-	public static function GetMethod() {
315
-		if (isset(self::$method)) {
316
-			return self::$method;
317
-		}
318
-
319
-		return self::UNKNOWN;
320
-	}
321
-
322
-	/**
323
-	 * Returns the value of the user parameter of the querystring.
324
-	 *
325
-	 * @return string/boolean       false if not available
326
-	 */
327
-	public static function GetGETUser() {
328
-		if (isset(self::$getUser)) {
329
-			return self::$getUser;
330
-		}
331
-
332
-		return self::UNKNOWN;
333
-	}
334
-
335
-	/**
336
-	 * Returns the value of the ItemId parameter of the querystring.
337
-	 *
338
-	 * @return string/boolean       false if not available
339
-	 */
340
-	public static function GetGETItemId() {
341
-		if (isset(self::$itemId)) {
342
-			return self::$itemId;
343
-		}
344
-
345
-		return false;
346
-	}
347
-
348
-	/**
349
-	 * Returns the value of the CollectionId parameter of the querystring.
350
-	 *
351
-	 * @return string/boolean       false if not available
352
-	 */
353
-	public static function GetGETCollectionId() {
354
-		if (isset(self::$collectionId)) {
355
-			return self::$collectionId;
356
-		}
357
-
358
-		return false;
359
-	}
360
-
361
-	/**
362
-	 * Returns if the SaveInSent parameter of the querystring is set.
363
-	 *
364
-	 * @return bool
365
-	 */
366
-	public static function GetGETSaveInSent() {
367
-		if (isset(self::$saveInSent)) {
368
-			return self::$saveInSent;
369
-		}
370
-
371
-		return true;
372
-	}
373
-
374
-	/**
375
-	 * Returns if the AcceptMultipart parameter of the querystring is set.
376
-	 *
377
-	 * @return bool
378
-	 */
379
-	public static function GetGETAcceptMultipart() {
380
-		if (isset(self::$acceptMultipart)) {
381
-			return self::$acceptMultipart;
382
-		}
383
-
384
-		return false;
385
-	}
386
-
387
-	/**
388
-	 * Returns the value of the AttachmentName parameter of the querystring.
389
-	 *
390
-	 * @return string/boolean       false if not available
391
-	 */
392
-	public static function GetGETAttachmentName() {
393
-		if (isset(self::$attachmentName)) {
394
-			return self::$attachmentName;
395
-		}
396
-
397
-		return false;
398
-	}
399
-
400
-	/**
401
-	 * Returns user that is synchronizing data.
402
-	 * If impersonation is active it returns the impersonated user,
403
-	 * else the auth user.
404
-	 *
405
-	 * @return string/boolean       false if not available
406
-	 */
407
-	public static function GetUser() {
408
-		if (self::GetImpersonatedUser()) {
409
-			return self::GetImpersonatedUser();
410
-		}
411
-
412
-		return self::GetAuthUser();
413
-	}
414
-
415
-	/**
416
-	 * Returns the AuthUser string send by the client.
417
-	 *
418
-	 * @return string/boolean       false if not available
419
-	 */
420
-	public static function GetAuthUserString() {
421
-		if (isset(self::$authUserString)) {
422
-			return self::$authUserString;
423
-		}
424
-
425
-		return false;
426
-	}
427
-
428
-	/**
429
-	 * Returns the impersonated user. If not available, returns false.
430
-	 *
431
-	 * @return string/boolean       false if not available
432
-	 */
433
-	public static function GetImpersonatedUser() {
434
-		if (isset(self::$impersonatedUser)) {
435
-			return self::$impersonatedUser;
436
-		}
437
-
438
-		return false;
439
-	}
440
-
441
-	/**
442
-	 * Returns the authenticated user.
443
-	 *
444
-	 * @return string/boolean       false if not available
445
-	 */
446
-	public static function GetAuthUser() {
447
-		if (isset(self::$authUser)) {
448
-			return self::$authUser;
449
-		}
450
-
451
-		return false;
452
-	}
453
-
454
-	/**
455
-	 * Returns the authenticated domain for the user.
456
-	 *
457
-	 * @return string/boolean       false if not available
458
-	 */
459
-	public static function GetAuthDomain() {
460
-		if (isset(self::$authDomain)) {
461
-			return self::$authDomain;
462
-		}
463
-
464
-		return false;
465
-	}
466
-
467
-	/**
468
-	 * Returns the transmitted password.
469
-	 *
470
-	 * @return string/boolean       false if not available
471
-	 */
472
-	public static function GetAuthPassword() {
473
-		if (isset(self::$authPassword)) {
474
-			return self::$authPassword;
475
-		}
476
-
477
-		return false;
478
-	}
479
-
480
-	/**
481
-	 * Returns the RemoteAddress.
482
-	 *
483
-	 * @return string
484
-	 */
485
-	public static function GetRemoteAddr() {
486
-		if (isset(self::$remoteAddr)) {
487
-			return self::$remoteAddr;
488
-		}
489
-
490
-		return "UNKNOWN";
491
-	}
492
-
493
-	/**
494
-	 * Returns the command to be executed.
495
-	 *
496
-	 * @return string/boolean       false if not available
497
-	 */
498
-	public static function GetCommand() {
499
-		if (isset(self::$command)) {
500
-			return self::$command;
501
-		}
502
-
503
-		return false;
504
-	}
505
-
506
-	/**
507
-	 * Returns the command code which is being executed.
508
-	 *
509
-	 * @return string/boolean       false if not available
510
-	 */
511
-	public static function GetCommandCode() {
512
-		if (isset(self::$command)) {
513
-			return Utils::GetCodeFromCommand(self::$command);
514
-		}
515
-
516
-		return false;
517
-	}
518
-
519
-	/**
520
-	 * Returns the device id transmitted.
521
-	 *
522
-	 * @return string/boolean       false if not available
523
-	 */
524
-	public static function GetDeviceID() {
525
-		if (isset(self::$devid)) {
526
-			return self::$devid;
527
-		}
528
-
529
-		return false;
530
-	}
531
-
532
-	/**
533
-	 * Returns the device type if transmitted.
534
-	 *
535
-	 * @return string/boolean       false if not available
536
-	 */
537
-	public static function GetDeviceType() {
538
-		if (isset(self::$devtype)) {
539
-			return self::$devtype;
540
-		}
541
-
542
-		return false;
543
-	}
544
-
545
-	/**
546
-	 * Returns the value of supported AS protocol from the headers.
547
-	 *
548
-	 * @return string/boolean       false if not available
549
-	 */
550
-	public static function GetProtocolVersion() {
551
-		if (isset(self::$asProtocolVersion)) {
552
-			return self::$asProtocolVersion;
553
-		}
554
-
555
-		return false;
556
-	}
557
-
558
-	/**
559
-	 * Returns the user agent sent in the headers.
560
-	 *
561
-	 * @return string/boolean       false if not available
562
-	 */
563
-	public static function GetUserAgent() {
564
-		if (isset(self::$useragent)) {
565
-			return self::$useragent;
566
-		}
567
-
568
-		return self::UNKNOWN;
569
-	}
570
-
571
-	/**
572
-	 * Returns policy key sent by the device.
573
-	 *
574
-	 * @return int/boolean       false if not available
575
-	 */
576
-	public static function GetPolicyKey() {
577
-		if (isset(self::$policykey)) {
578
-			return self::$policykey;
579
-		}
580
-
581
-		return false;
582
-	}
583
-
584
-	/**
585
-	 * Indicates if a policy key was sent by the device.
586
-	 *
587
-	 * @return bool
588
-	 */
589
-	public static function WasPolicyKeySent() {
590
-		return isset(self::$headers["x-ms-policykey"]);
591
-	}
592
-
593
-	/**
594
-	 * Indicates if grommunio-sync was called with a POST request.
595
-	 *
596
-	 * @return bool
597
-	 */
598
-	public static function IsMethodPOST() {
599
-		return self::$method == "POST";
600
-	}
601
-
602
-	/**
603
-	 * Indicates if grommunio-sync was called with a GET request.
604
-	 *
605
-	 * @return bool
606
-	 */
607
-	public static function IsMethodGET() {
608
-		return self::$method == "GET";
609
-	}
610
-
611
-	/**
612
-	 * Indicates if grommunio-sync was called with a OPTIONS request.
613
-	 *
614
-	 * @return bool
615
-	 */
616
-	public static function IsMethodOPTIONS() {
617
-		return self::$method == "OPTIONS";
618
-	}
619
-
620
-	/**
621
-	 * Sometimes strange device ids are submitted
622
-	 * No device information should be saved when this happens.
623
-	 *
624
-	 * @return bool false if invalid
625
-	 */
626
-	public static function IsValidDeviceID() {
627
-		if (self::GetDeviceID() === "validate") {
628
-			return false;
629
-		}
630
-
631
-		return true;
632
-	}
633
-
634
-	/**
635
-	 * Returns the amount of data sent in this request (from the headers).
636
-	 *
637
-	 * @return int
638
-	 */
639
-	public static function GetContentLength() {
640
-		return (isset(self::$headers["content-length"])) ? (int) self::$headers["content-length"] : 0;
641
-	}
642
-
643
-	/**
644
-	 * Returns the amount of seconds this request is able to be kept open without the client
645
-	 * closing it. This depends on the vendor.
646
-	 *
647
-	 * @return bool
648
-	 */
649
-	public static function GetExpectedConnectionTimeout() {
650
-		// Different vendors implement different connection timeouts.
651
-		// In order to optimize processing, we return a specific time for the major
652
-		// classes currently known (feedback welcome).
653
-		// The amount of time returned is somehow lower than the max timeout so we have
654
-		// time for processing.
655
-
656
-		if (!isset(self::$expectedConnectionTimeout)) {
657
-			// Apple and Windows Phone have higher timeouts (4min = 240sec)
658
-			if (stripos(SYNC_TIMEOUT_LONG_DEVICETYPES, self::GetDeviceType()) !== false) {
659
-				self::$expectedConnectionTimeout = 210;
660
-			}
661
-			// Samsung devices have a intermediate timeout (90sec)
662
-			elseif (stripos(SYNC_TIMEOUT_MEDIUM_DEVICETYPES, self::GetDeviceType()) !== false) {
663
-				self::$expectedConnectionTimeout = 85;
664
-			}
665
-			else {
666
-				// for all other devices, a timeout of 30 seconds is expected
667
-				self::$expectedConnectionTimeout = 28;
668
-			}
669
-		}
670
-
671
-		return self::$expectedConnectionTimeout;
672
-	}
673
-
674
-	/**
675
-	 * Indicates if the maximum timeout for the devicetype of this request is
676
-	 * almost reached.
677
-	 *
678
-	 * @return bool
679
-	 */
680
-	public static function IsRequestTimeoutReached() {
681
-		return (time() - $_SERVER["REQUEST_TIME"]) >= self::GetExpectedConnectionTimeout();
682
-	}
683
-
684
-	/**
685
-	 * Indicates if the memory usage limit is almost reached.
686
-	 * Processing should stop then to prevent hard out-of-memory issues.
687
-	 * The threshold is hardcoded at 90% in Request::MAXMEMORYUSAGE.
688
-	 *
689
-	 * @return bool
690
-	 */
691
-	public static function IsRequestMemoryLimitReached() {
692
-		if (self::$memoryLimit === false) {
693
-			return false;
694
-		}
695
-
696
-		return memory_get_peak_usage(true) >= self::$memoryLimit;
697
-	}
698
-
699
-	/*----------------------------------------------------------------------------------------------------------
283
+    /**
284
+     * Returns the input stream.
285
+     *
286
+     * @return handle/boolean      false if not available
287
+     */
288
+    public static function GetInputStream() {
289
+        if (isset(self::$input)) {
290
+            return self::$input;
291
+        }
292
+
293
+        return false;
294
+    }
295
+
296
+    /**
297
+     * Returns the output stream.
298
+     *
299
+     * @return handle/boolean      false if not available
300
+     */
301
+    public static function GetOutputStream() {
302
+        if (isset(self::$output)) {
303
+            return self::$output;
304
+        }
305
+
306
+        return false;
307
+    }
308
+
309
+    /**
310
+     * Returns the request method.
311
+     *
312
+     * @return string
313
+     */
314
+    public static function GetMethod() {
315
+        if (isset(self::$method)) {
316
+            return self::$method;
317
+        }
318
+
319
+        return self::UNKNOWN;
320
+    }
321
+
322
+    /**
323
+     * Returns the value of the user parameter of the querystring.
324
+     *
325
+     * @return string/boolean       false if not available
326
+     */
327
+    public static function GetGETUser() {
328
+        if (isset(self::$getUser)) {
329
+            return self::$getUser;
330
+        }
331
+
332
+        return self::UNKNOWN;
333
+    }
334
+
335
+    /**
336
+     * Returns the value of the ItemId parameter of the querystring.
337
+     *
338
+     * @return string/boolean       false if not available
339
+     */
340
+    public static function GetGETItemId() {
341
+        if (isset(self::$itemId)) {
342
+            return self::$itemId;
343
+        }
344
+
345
+        return false;
346
+    }
347
+
348
+    /**
349
+     * Returns the value of the CollectionId parameter of the querystring.
350
+     *
351
+     * @return string/boolean       false if not available
352
+     */
353
+    public static function GetGETCollectionId() {
354
+        if (isset(self::$collectionId)) {
355
+            return self::$collectionId;
356
+        }
357
+
358
+        return false;
359
+    }
360
+
361
+    /**
362
+     * Returns if the SaveInSent parameter of the querystring is set.
363
+     *
364
+     * @return bool
365
+     */
366
+    public static function GetGETSaveInSent() {
367
+        if (isset(self::$saveInSent)) {
368
+            return self::$saveInSent;
369
+        }
370
+
371
+        return true;
372
+    }
373
+
374
+    /**
375
+     * Returns if the AcceptMultipart parameter of the querystring is set.
376
+     *
377
+     * @return bool
378
+     */
379
+    public static function GetGETAcceptMultipart() {
380
+        if (isset(self::$acceptMultipart)) {
381
+            return self::$acceptMultipart;
382
+        }
383
+
384
+        return false;
385
+    }
386
+
387
+    /**
388
+     * Returns the value of the AttachmentName parameter of the querystring.
389
+     *
390
+     * @return string/boolean       false if not available
391
+     */
392
+    public static function GetGETAttachmentName() {
393
+        if (isset(self::$attachmentName)) {
394
+            return self::$attachmentName;
395
+        }
396
+
397
+        return false;
398
+    }
399
+
400
+    /**
401
+     * Returns user that is synchronizing data.
402
+     * If impersonation is active it returns the impersonated user,
403
+     * else the auth user.
404
+     *
405
+     * @return string/boolean       false if not available
406
+     */
407
+    public static function GetUser() {
408
+        if (self::GetImpersonatedUser()) {
409
+            return self::GetImpersonatedUser();
410
+        }
411
+
412
+        return self::GetAuthUser();
413
+    }
414
+
415
+    /**
416
+     * Returns the AuthUser string send by the client.
417
+     *
418
+     * @return string/boolean       false if not available
419
+     */
420
+    public static function GetAuthUserString() {
421
+        if (isset(self::$authUserString)) {
422
+            return self::$authUserString;
423
+        }
424
+
425
+        return false;
426
+    }
427
+
428
+    /**
429
+     * Returns the impersonated user. If not available, returns false.
430
+     *
431
+     * @return string/boolean       false if not available
432
+     */
433
+    public static function GetImpersonatedUser() {
434
+        if (isset(self::$impersonatedUser)) {
435
+            return self::$impersonatedUser;
436
+        }
437
+
438
+        return false;
439
+    }
440
+
441
+    /**
442
+     * Returns the authenticated user.
443
+     *
444
+     * @return string/boolean       false if not available
445
+     */
446
+    public static function GetAuthUser() {
447
+        if (isset(self::$authUser)) {
448
+            return self::$authUser;
449
+        }
450
+
451
+        return false;
452
+    }
453
+
454
+    /**
455
+     * Returns the authenticated domain for the user.
456
+     *
457
+     * @return string/boolean       false if not available
458
+     */
459
+    public static function GetAuthDomain() {
460
+        if (isset(self::$authDomain)) {
461
+            return self::$authDomain;
462
+        }
463
+
464
+        return false;
465
+    }
466
+
467
+    /**
468
+     * Returns the transmitted password.
469
+     *
470
+     * @return string/boolean       false if not available
471
+     */
472
+    public static function GetAuthPassword() {
473
+        if (isset(self::$authPassword)) {
474
+            return self::$authPassword;
475
+        }
476
+
477
+        return false;
478
+    }
479
+
480
+    /**
481
+     * Returns the RemoteAddress.
482
+     *
483
+     * @return string
484
+     */
485
+    public static function GetRemoteAddr() {
486
+        if (isset(self::$remoteAddr)) {
487
+            return self::$remoteAddr;
488
+        }
489
+
490
+        return "UNKNOWN";
491
+    }
492
+
493
+    /**
494
+     * Returns the command to be executed.
495
+     *
496
+     * @return string/boolean       false if not available
497
+     */
498
+    public static function GetCommand() {
499
+        if (isset(self::$command)) {
500
+            return self::$command;
501
+        }
502
+
503
+        return false;
504
+    }
505
+
506
+    /**
507
+     * Returns the command code which is being executed.
508
+     *
509
+     * @return string/boolean       false if not available
510
+     */
511
+    public static function GetCommandCode() {
512
+        if (isset(self::$command)) {
513
+            return Utils::GetCodeFromCommand(self::$command);
514
+        }
515
+
516
+        return false;
517
+    }
518
+
519
+    /**
520
+     * Returns the device id transmitted.
521
+     *
522
+     * @return string/boolean       false if not available
523
+     */
524
+    public static function GetDeviceID() {
525
+        if (isset(self::$devid)) {
526
+            return self::$devid;
527
+        }
528
+
529
+        return false;
530
+    }
531
+
532
+    /**
533
+     * Returns the device type if transmitted.
534
+     *
535
+     * @return string/boolean       false if not available
536
+     */
537
+    public static function GetDeviceType() {
538
+        if (isset(self::$devtype)) {
539
+            return self::$devtype;
540
+        }
541
+
542
+        return false;
543
+    }
544
+
545
+    /**
546
+     * Returns the value of supported AS protocol from the headers.
547
+     *
548
+     * @return string/boolean       false if not available
549
+     */
550
+    public static function GetProtocolVersion() {
551
+        if (isset(self::$asProtocolVersion)) {
552
+            return self::$asProtocolVersion;
553
+        }
554
+
555
+        return false;
556
+    }
557
+
558
+    /**
559
+     * Returns the user agent sent in the headers.
560
+     *
561
+     * @return string/boolean       false if not available
562
+     */
563
+    public static function GetUserAgent() {
564
+        if (isset(self::$useragent)) {
565
+            return self::$useragent;
566
+        }
567
+
568
+        return self::UNKNOWN;
569
+    }
570
+
571
+    /**
572
+     * Returns policy key sent by the device.
573
+     *
574
+     * @return int/boolean       false if not available
575
+     */
576
+    public static function GetPolicyKey() {
577
+        if (isset(self::$policykey)) {
578
+            return self::$policykey;
579
+        }
580
+
581
+        return false;
582
+    }
583
+
584
+    /**
585
+     * Indicates if a policy key was sent by the device.
586
+     *
587
+     * @return bool
588
+     */
589
+    public static function WasPolicyKeySent() {
590
+        return isset(self::$headers["x-ms-policykey"]);
591
+    }
592
+
593
+    /**
594
+     * Indicates if grommunio-sync was called with a POST request.
595
+     *
596
+     * @return bool
597
+     */
598
+    public static function IsMethodPOST() {
599
+        return self::$method == "POST";
600
+    }
601
+
602
+    /**
603
+     * Indicates if grommunio-sync was called with a GET request.
604
+     *
605
+     * @return bool
606
+     */
607
+    public static function IsMethodGET() {
608
+        return self::$method == "GET";
609
+    }
610
+
611
+    /**
612
+     * Indicates if grommunio-sync was called with a OPTIONS request.
613
+     *
614
+     * @return bool
615
+     */
616
+    public static function IsMethodOPTIONS() {
617
+        return self::$method == "OPTIONS";
618
+    }
619
+
620
+    /**
621
+     * Sometimes strange device ids are submitted
622
+     * No device information should be saved when this happens.
623
+     *
624
+     * @return bool false if invalid
625
+     */
626
+    public static function IsValidDeviceID() {
627
+        if (self::GetDeviceID() === "validate") {
628
+            return false;
629
+        }
630
+
631
+        return true;
632
+    }
633
+
634
+    /**
635
+     * Returns the amount of data sent in this request (from the headers).
636
+     *
637
+     * @return int
638
+     */
639
+    public static function GetContentLength() {
640
+        return (isset(self::$headers["content-length"])) ? (int) self::$headers["content-length"] : 0;
641
+    }
642
+
643
+    /**
644
+     * Returns the amount of seconds this request is able to be kept open without the client
645
+     * closing it. This depends on the vendor.
646
+     *
647
+     * @return bool
648
+     */
649
+    public static function GetExpectedConnectionTimeout() {
650
+        // Different vendors implement different connection timeouts.
651
+        // In order to optimize processing, we return a specific time for the major
652
+        // classes currently known (feedback welcome).
653
+        // The amount of time returned is somehow lower than the max timeout so we have
654
+        // time for processing.
655
+
656
+        if (!isset(self::$expectedConnectionTimeout)) {
657
+            // Apple and Windows Phone have higher timeouts (4min = 240sec)
658
+            if (stripos(SYNC_TIMEOUT_LONG_DEVICETYPES, self::GetDeviceType()) !== false) {
659
+                self::$expectedConnectionTimeout = 210;
660
+            }
661
+            // Samsung devices have a intermediate timeout (90sec)
662
+            elseif (stripos(SYNC_TIMEOUT_MEDIUM_DEVICETYPES, self::GetDeviceType()) !== false) {
663
+                self::$expectedConnectionTimeout = 85;
664
+            }
665
+            else {
666
+                // for all other devices, a timeout of 30 seconds is expected
667
+                self::$expectedConnectionTimeout = 28;
668
+            }
669
+        }
670
+
671
+        return self::$expectedConnectionTimeout;
672
+    }
673
+
674
+    /**
675
+     * Indicates if the maximum timeout for the devicetype of this request is
676
+     * almost reached.
677
+     *
678
+     * @return bool
679
+     */
680
+    public static function IsRequestTimeoutReached() {
681
+        return (time() - $_SERVER["REQUEST_TIME"]) >= self::GetExpectedConnectionTimeout();
682
+    }
683
+
684
+    /**
685
+     * Indicates if the memory usage limit is almost reached.
686
+     * Processing should stop then to prevent hard out-of-memory issues.
687
+     * The threshold is hardcoded at 90% in Request::MAXMEMORYUSAGE.
688
+     *
689
+     * @return bool
690
+     */
691
+    public static function IsRequestMemoryLimitReached() {
692
+        if (self::$memoryLimit === false) {
693
+            return false;
694
+        }
695
+
696
+        return memory_get_peak_usage(true) >= self::$memoryLimit;
697
+    }
698
+
699
+    /*----------------------------------------------------------------------------------------------------------
700 700
 	 * Private stuff
701 701
 	 */
702 702
 
703
-	/**
704
-	 * Replaces all not allowed characters in a string.
705
-	 *
706
-	 * @param string $input        the input string
707
-	 * @param int    $filter       one of the predefined filters: LETTERS_ONLY, HEX_ONLY, WORDCHAR_ONLY, NUMBERS_ONLY, NUMBERSDOT_ONLY
708
-	 * @param char   $replacevalue (opt) a character the filtered characters should be replaced with
709
-	 *
710
-	 * @return string
711
-	 */
712
-	private static function filterEvilInput($input, $filter, $replacevalue = '') {
713
-		$re = false;
714
-		if ($filter == self::LETTERS_ONLY) {
715
-			$re = "/[^A-Za-z]/";
716
-		}
717
-		elseif ($filter == self::HEX_ONLY) {
718
-			$re = "/[^A-Fa-f0-9]/";
719
-		}
720
-		elseif ($filter == self::WORDCHAR_ONLY) {
721
-			$re = "/[^A-Za-z0-9]/";
722
-		}
723
-		elseif ($filter == self::NUMBERS_ONLY) {
724
-			$re = "/[^0-9]/";
725
-		}
726
-		elseif ($filter == self::NUMBERSDOT_ONLY) {
727
-			$re = "/[^0-9\\.]/";
728
-		}
729
-		elseif ($filter == self::HEX_EXTENDED) {
730
-			$re = "/[^A-Fa-f0-9\\:\\.]/";
731
-		}
732
-		elseif ($filter == self::HEX_EXTENDED2) {
733
-			$re = "/[^A-Fa-f0-9\\:USGI]/";
734
-		} // Folder origin constants from DeviceManager::FLD_ORIGIN_* (C already hex)
735
-		elseif ($filter == self::ISO8601) {
736
-			$re = "/[^\\d{8}T\\d{6}Z]/";
737
-		}
738
-
739
-		return ($re) ? preg_replace($re, $replacevalue, $input) : '';
740
-	}
741
-
742
-	/**
743
-	 * If $input is a valid IPv4 or IPv6 address, returns a valid compact IPv4 or IPv6 address string.
744
-	 * Otherwise, it will strip all characters that are neither numerical or '.' and prefix with "bad-ip".
745
-	 *
746
-	 * @param string $input The ipv4/ipv6 address
747
-	 *
748
-	 * @return string
749
-	 */
750
-	private static function filterIP($input) {
751
-		$in_addr = @inet_pton($input);
752
-		if ($in_addr === false) {
753
-			return 'badip-' . self::filterEvilInput($input, self::HEX_EXTENDED);
754
-		}
755
-
756
-		return inet_ntop($in_addr);
757
-	}
758
-
759
-	/**
760
-	 * Returns base64 encoded "php://input"
761
-	 * With POST request (our case), you can open and read
762
-	 * multiple times "php://input".
763
-	 *
764
-	 * @param int $maxLength max. length to be returned. Default: return all
765
-	 *
766
-	 * @return string - base64 encoded wbxml
767
-	 */
768
-	public static function GetInputAsBase64($maxLength = -1) {
769
-		$input = fopen('php://input', 'r');
770
-		$wbxml = base64_encode(stream_get_contents($input, $maxLength));
771
-		fclose($input);
772
-
773
-		return $wbxml;
774
-	}
775
-
776
-	/**
777
-	 * Decodes base64 encoded query parameters. Based on dw2412 contribution.
778
-	 */
779
-	private static function decodeBase64URI() {
780
-		/*
703
+    /**
704
+     * Replaces all not allowed characters in a string.
705
+     *
706
+     * @param string $input        the input string
707
+     * @param int    $filter       one of the predefined filters: LETTERS_ONLY, HEX_ONLY, WORDCHAR_ONLY, NUMBERS_ONLY, NUMBERSDOT_ONLY
708
+     * @param char   $replacevalue (opt) a character the filtered characters should be replaced with
709
+     *
710
+     * @return string
711
+     */
712
+    private static function filterEvilInput($input, $filter, $replacevalue = '') {
713
+        $re = false;
714
+        if ($filter == self::LETTERS_ONLY) {
715
+            $re = "/[^A-Za-z]/";
716
+        }
717
+        elseif ($filter == self::HEX_ONLY) {
718
+            $re = "/[^A-Fa-f0-9]/";
719
+        }
720
+        elseif ($filter == self::WORDCHAR_ONLY) {
721
+            $re = "/[^A-Za-z0-9]/";
722
+        }
723
+        elseif ($filter == self::NUMBERS_ONLY) {
724
+            $re = "/[^0-9]/";
725
+        }
726
+        elseif ($filter == self::NUMBERSDOT_ONLY) {
727
+            $re = "/[^0-9\\.]/";
728
+        }
729
+        elseif ($filter == self::HEX_EXTENDED) {
730
+            $re = "/[^A-Fa-f0-9\\:\\.]/";
731
+        }
732
+        elseif ($filter == self::HEX_EXTENDED2) {
733
+            $re = "/[^A-Fa-f0-9\\:USGI]/";
734
+        } // Folder origin constants from DeviceManager::FLD_ORIGIN_* (C already hex)
735
+        elseif ($filter == self::ISO8601) {
736
+            $re = "/[^\\d{8}T\\d{6}Z]/";
737
+        }
738
+
739
+        return ($re) ? preg_replace($re, $replacevalue, $input) : '';
740
+    }
741
+
742
+    /**
743
+     * If $input is a valid IPv4 or IPv6 address, returns a valid compact IPv4 or IPv6 address string.
744
+     * Otherwise, it will strip all characters that are neither numerical or '.' and prefix with "bad-ip".
745
+     *
746
+     * @param string $input The ipv4/ipv6 address
747
+     *
748
+     * @return string
749
+     */
750
+    private static function filterIP($input) {
751
+        $in_addr = @inet_pton($input);
752
+        if ($in_addr === false) {
753
+            return 'badip-' . self::filterEvilInput($input, self::HEX_EXTENDED);
754
+        }
755
+
756
+        return inet_ntop($in_addr);
757
+    }
758
+
759
+    /**
760
+     * Returns base64 encoded "php://input"
761
+     * With POST request (our case), you can open and read
762
+     * multiple times "php://input".
763
+     *
764
+     * @param int $maxLength max. length to be returned. Default: return all
765
+     *
766
+     * @return string - base64 encoded wbxml
767
+     */
768
+    public static function GetInputAsBase64($maxLength = -1) {
769
+        $input = fopen('php://input', 'r');
770
+        $wbxml = base64_encode(stream_get_contents($input, $maxLength));
771
+        fclose($input);
772
+
773
+        return $wbxml;
774
+    }
775
+
776
+    /**
777
+     * Decodes base64 encoded query parameters. Based on dw2412 contribution.
778
+     */
779
+    private static function decodeBase64URI() {
780
+        /*
781 781
 		 * The query string has a following structure. Number in () is position:
782 782
 		 * 1 byte       - protocol version (0)
783 783
 		 * 1 byte       - command code (1)
@@ -794,22 +794,22 @@  discard block
 block discarded – undo
794 794
 		 *                      variable    - value of the parameter
795 795
 		 *
796 796
 		 */
797
-		$decoded = base64_decode($_SERVER['QUERY_STRING']);
798
-		$devIdLength = ord($decoded[4]); // device ID length
799
-		$polKeyLength = ord($decoded[5 + $devIdLength]); // policy key length
800
-		$devTypeLength = ord($decoded[6 + $devIdLength + $polKeyLength]); // device type length
801
-		// unpack the decoded query string values
802
-		self::$base64QueryDecoded = unpack("CProtVer/CCommand/vLocale/CDevIDLen/H" . ($devIdLength * 2) . "DevID/CPolKeyLen" . ($polKeyLength == 4 ? "/VPolKey" : "") . "/CDevTypeLen/A" . ($devTypeLength) . "DevType", $decoded);
803
-
804
-		// get the command parameters
805
-		$pos = 7 + $devIdLength + $polKeyLength + $devTypeLength;
806
-		$decoded = substr($decoded, $pos);
807
-		while (strlen($decoded) > 0) {
808
-			$paramLength = ord($decoded[1]);
809
-			$unpackedParam = unpack("CParamTag/CParamLength/A" . $paramLength . "ParamValue", $decoded);
810
-			self::$base64QueryDecoded[ord($decoded[0])] = $unpackedParam['ParamValue'];
811
-			// remove parameter from decoded query string
812
-			$decoded = substr($decoded, 2 + $paramLength);
813
-		}
814
-	}
797
+        $decoded = base64_decode($_SERVER['QUERY_STRING']);
798
+        $devIdLength = ord($decoded[4]); // device ID length
799
+        $polKeyLength = ord($decoded[5 + $devIdLength]); // policy key length
800
+        $devTypeLength = ord($decoded[6 + $devIdLength + $polKeyLength]); // device type length
801
+        // unpack the decoded query string values
802
+        self::$base64QueryDecoded = unpack("CProtVer/CCommand/vLocale/CDevIDLen/H" . ($devIdLength * 2) . "DevID/CPolKeyLen" . ($polKeyLength == 4 ? "/VPolKey" : "") . "/CDevTypeLen/A" . ($devTypeLength) . "DevType", $decoded);
803
+
804
+        // get the command parameters
805
+        $pos = 7 + $devIdLength + $polKeyLength + $devTypeLength;
806
+        $decoded = substr($decoded, $pos);
807
+        while (strlen($decoded) > 0) {
808
+            $paramLength = ord($decoded[1]);
809
+            $unpackedParam = unpack("CParamTag/CParamLength/A" . $paramLength . "ParamValue", $decoded);
810
+            self::$base64QueryDecoded[ord($decoded[0])] = $unpackedParam['ParamValue'];
811
+            // remove parameter from decoded query string
812
+            $decoded = substr($decoded, 2 + $paramLength);
813
+        }
814
+    }
815 815
 }
Please login to merge, or discard this patch.
Spacing   +8 added lines, -8 removed lines patch added patch discarded remove patch
@@ -8,7 +8,7 @@  discard block
 block discarded – undo
8 8
  */
9 9
 
10 10
 class Request {
11
-	public const MAXMEMORYUSAGE = 0.9;     // use max. 90% of allowed memory when syncing
11
+	public const MAXMEMORYUSAGE = 0.9; // use max. 90% of allowed memory when syncing
12 12
 	public const UNKNOWN = "unknown";
13 13
 	public const IMPERSONATE_DELIM = '#';
14 14
 
@@ -140,7 +140,7 @@  discard block
 block discarded – undo
140 140
 			}
141 141
 
142 142
 			if (isset(self::$base64QueryDecoded['PolKey'])) {
143
-				self::$policykey = (int) self::filterEvilInput(self::$base64QueryDecoded['PolKey'], self::NUMBERS_ONLY);
143
+				self::$policykey = (int)self::filterEvilInput(self::$base64QueryDecoded['PolKey'], self::NUMBERS_ONLY);
144 144
 			}
145 145
 
146 146
 			if (isset(self::$base64QueryDecoded['ProtVer'])) {
@@ -198,7 +198,7 @@  discard block
 block discarded – undo
198 198
 		else {
199 199
 			preg_replace_callback(
200 200
 				'/(\-?\d+)(.?)/',
201
-				function ($m) {
201
+				function($m) {
202 202
 					self::$memoryLimit = $m[1] * pow(1024, strpos('BKMG', $m[2])) * self::MAXMEMORYUSAGE;
203 203
 				},
204 204
 				strtoupper($memoryLimit)
@@ -222,7 +222,7 @@  discard block
 block discarded – undo
222 222
 		// the policy key might be set in Request::Initialize from the base64 encoded query
223 223
 		if (!isset(self::$policykey)) {
224 224
 			if (isset(self::$headers["x-ms-policykey"])) {
225
-				self::$policykey = (int) self::filterEvilInput(self::$headers["x-ms-policykey"], self::NUMBERS_ONLY);
225
+				self::$policykey = (int)self::filterEvilInput(self::$headers["x-ms-policykey"], self::NUMBERS_ONLY);
226 226
 			}
227 227
 			else {
228 228
 				self::$policykey = 0;
@@ -637,7 +637,7 @@  discard block
 block discarded – undo
637 637
 	 * @return int
638 638
 	 */
639 639
 	public static function GetContentLength() {
640
-		return (isset(self::$headers["content-length"])) ? (int) self::$headers["content-length"] : 0;
640
+		return (isset(self::$headers["content-length"])) ? (int)self::$headers["content-length"] : 0;
641 641
 	}
642 642
 
643 643
 	/**
@@ -750,7 +750,7 @@  discard block
 block discarded – undo
750 750
 	private static function filterIP($input) {
751 751
 		$in_addr = @inet_pton($input);
752 752
 		if ($in_addr === false) {
753
-			return 'badip-' . self::filterEvilInput($input, self::HEX_EXTENDED);
753
+			return 'badip-'.self::filterEvilInput($input, self::HEX_EXTENDED);
754 754
 		}
755 755
 
756 756
 		return inet_ntop($in_addr);
@@ -799,14 +799,14 @@  discard block
 block discarded – undo
799 799
 		$polKeyLength = ord($decoded[5 + $devIdLength]); // policy key length
800 800
 		$devTypeLength = ord($decoded[6 + $devIdLength + $polKeyLength]); // device type length
801 801
 		// unpack the decoded query string values
802
-		self::$base64QueryDecoded = unpack("CProtVer/CCommand/vLocale/CDevIDLen/H" . ($devIdLength * 2) . "DevID/CPolKeyLen" . ($polKeyLength == 4 ? "/VPolKey" : "") . "/CDevTypeLen/A" . ($devTypeLength) . "DevType", $decoded);
802
+		self::$base64QueryDecoded = unpack("CProtVer/CCommand/vLocale/CDevIDLen/H".($devIdLength * 2)."DevID/CPolKeyLen".($polKeyLength == 4 ? "/VPolKey" : "")."/CDevTypeLen/A".($devTypeLength)."DevType", $decoded);
803 803
 
804 804
 		// get the command parameters
805 805
 		$pos = 7 + $devIdLength + $polKeyLength + $devTypeLength;
806 806
 		$decoded = substr($decoded, $pos);
807 807
 		while (strlen($decoded) > 0) {
808 808
 			$paramLength = ord($decoded[1]);
809
-			$unpackedParam = unpack("CParamTag/CParamLength/A" . $paramLength . "ParamValue", $decoded);
809
+			$unpackedParam = unpack("CParamTag/CParamLength/A".$paramLength."ParamValue", $decoded);
810 810
 			self::$base64QueryDecoded[ord($decoded[0])] = $unpackedParam['ParamValue'];
811 811
 			// remove parameter from decoded query string
812 812
 			$decoded = substr($decoded, 2 + $paramLength);
Please login to merge, or discard this patch.
Braces   +9 added lines, -18 removed lines patch added patch discarded remove patch
@@ -194,8 +194,7 @@  discard block
 block discarded – undo
194 194
 		$memoryLimit = ini_get('memory_limit');
195 195
 		if ($memoryLimit == -1) {
196 196
 			self::$memoryLimit = false;
197
-		}
198
-		else {
197
+		} else {
199 198
 			preg_replace_callback(
200 199
 				'/(\-?\d+)(.?)/',
201 200
 				function ($m) {
@@ -223,8 +222,7 @@  discard block
 block discarded – undo
223 222
 		if (!isset(self::$policykey)) {
224 223
 			if (isset(self::$headers["x-ms-policykey"])) {
225 224
 				self::$policykey = (int) self::filterEvilInput(self::$headers["x-ms-policykey"], self::NUMBERS_ONLY);
226
-			}
227
-			else {
225
+			} else {
228 226
 				self::$policykey = 0;
229 227
 			}
230 228
 		}
@@ -661,8 +659,7 @@  discard block
 block discarded – undo
661 659
 			// Samsung devices have a intermediate timeout (90sec)
662 660
 			elseif (stripos(SYNC_TIMEOUT_MEDIUM_DEVICETYPES, self::GetDeviceType()) !== false) {
663 661
 				self::$expectedConnectionTimeout = 85;
664
-			}
665
-			else {
662
+			} else {
666 663
 				// for all other devices, a timeout of 30 seconds is expected
667 664
 				self::$expectedConnectionTimeout = 28;
668 665
 			}
@@ -713,23 +710,17 @@  discard block
 block discarded – undo
713 710
 		$re = false;
714 711
 		if ($filter == self::LETTERS_ONLY) {
715 712
 			$re = "/[^A-Za-z]/";
716
-		}
717
-		elseif ($filter == self::HEX_ONLY) {
713
+		} elseif ($filter == self::HEX_ONLY) {
718 714
 			$re = "/[^A-Fa-f0-9]/";
719
-		}
720
-		elseif ($filter == self::WORDCHAR_ONLY) {
715
+		} elseif ($filter == self::WORDCHAR_ONLY) {
721 716
 			$re = "/[^A-Za-z0-9]/";
722
-		}
723
-		elseif ($filter == self::NUMBERS_ONLY) {
717
+		} elseif ($filter == self::NUMBERS_ONLY) {
724 718
 			$re = "/[^0-9]/";
725
-		}
726
-		elseif ($filter == self::NUMBERSDOT_ONLY) {
719
+		} elseif ($filter == self::NUMBERSDOT_ONLY) {
727 720
 			$re = "/[^0-9\\.]/";
728
-		}
729
-		elseif ($filter == self::HEX_EXTENDED) {
721
+		} elseif ($filter == self::HEX_EXTENDED) {
730 722
 			$re = "/[^A-Fa-f0-9\\:\\.]/";
731
-		}
732
-		elseif ($filter == self::HEX_EXTENDED2) {
723
+		} elseif ($filter == self::HEX_EXTENDED2) {
733 724
 			$re = "/[^A-Fa-f0-9\\:USGI]/";
734 725
 		} // Folder origin constants from DeviceManager::FLD_ORIGIN_* (C already hex)
735 726
 		elseif ($filter == self::ISO8601) {
Please login to merge, or discard this patch.
lib/request/getitemestimate.php 3 patches
Indentation   +262 added lines, -262 removed lines patch added patch discarded remove patch
@@ -8,266 +8,266 @@
 block discarded – undo
8 8
  */
9 9
 
10 10
 class GetItemEstimate extends RequestProcessor {
11
-	/**
12
-	 * Handles the GetItemEstimate command
13
-	 * Returns an estimation of how many items will be synchronized at the next sync
14
-	 * This is mostly used to show something in the progress bar.
15
-	 *
16
-	 * @param int $commandCode
17
-	 *
18
-	 * @return bool
19
-	 */
20
-	public function Handle($commandCode) {
21
-		$sc = new SyncCollections();
22
-
23
-		if (!self::$decoder->getElementStartTag(SYNC_GETITEMESTIMATE_GETITEMESTIMATE)) {
24
-			return false;
25
-		}
26
-
27
-		if (!self::$decoder->getElementStartTag(SYNC_GETITEMESTIMATE_FOLDERS)) {
28
-			return false;
29
-		}
30
-
31
-		while (self::$decoder->getElementStartTag(SYNC_GETITEMESTIMATE_FOLDER)) {
32
-			$spa = new SyncParameters();
33
-			$spastatus = false;
34
-
35
-			// read the folder properties
36
-			WBXMLDecoder::ResetInWhile("getItemEstimateFolders");
37
-			while (WBXMLDecoder::InWhile("getItemEstimateFolders")) {
38
-				if (self::$decoder->getElementStartTag(SYNC_SYNCKEY)) {
39
-					try {
40
-						$spa->SetSyncKey(self::$decoder->getElementContent());
41
-					}
42
-					catch (StateInvalidException $siex) {
43
-						$spastatus = SYNC_GETITEMESTSTATUS_SYNCSTATENOTPRIMED;
44
-					}
45
-
46
-					if (!self::$decoder->getElementEndTag()) {
47
-						return false;
48
-					}
49
-				}
50
-				elseif (self::$decoder->getElementStartTag(SYNC_GETITEMESTIMATE_FOLDERID)) {
51
-					$fid = self::$decoder->getElementContent();
52
-					$spa->SetFolderId($fid);
53
-					$spa->SetBackendFolderId(self::$deviceManager->GetBackendIdForFolderId($fid));
54
-
55
-					if (!self::$decoder->getElementEndTag()) {
56
-						return false;
57
-					}
58
-				}
59
-
60
-				// conversation mode requested
61
-				elseif (self::$decoder->getElementStartTag(SYNC_CONVERSATIONMODE)) {
62
-					$spa->SetConversationMode(true);
63
-					if (($conversationmode = self::$decoder->getElementContent()) !== false) {
64
-						$spa->SetConversationMode((bool) $conversationmode);
65
-						if (!self::$decoder->getElementEndTag()) {
66
-							return false;
67
-						}
68
-					}
69
-				}
70
-
71
-				// get items estimate does not necessarily send the folder type
72
-				elseif (self::$decoder->getElementStartTag(SYNC_GETITEMESTIMATE_FOLDERTYPE)) {
73
-					$spa->SetContentClass(self::$decoder->getElementContent());
74
-
75
-					if (!self::$decoder->getElementEndTag()) {
76
-						return false;
77
-					}
78
-				}
79
-
80
-				// TODO AS 2.5 and filtertype not set
81
-				elseif (self::$decoder->getElementStartTag(SYNC_FILTERTYPE)) {
82
-					$spa->SetFilterType(self::$decoder->getElementContent());
83
-
84
-					if (!self::$decoder->getElementEndTag()) {
85
-						return false;
86
-					}
87
-				}
88
-
89
-				while (self::$decoder->getElementStartTag(SYNC_OPTIONS)) {
90
-					WBXMLDecoder::ResetInWhile("getItemEstimateOptions");
91
-					while (WBXMLDecoder::InWhile("getItemEstimateOptions")) {
92
-						$firstOption = true;
93
-						// foldertype definition
94
-						if (self::$decoder->getElementStartTag(SYNC_FOLDERTYPE)) {
95
-							$foldertype = self::$decoder->getElementContent();
96
-							SLog::Write(LOGLEVEL_DEBUG, sprintf("HandleGetItemEstimate(): specified options block with foldertype '%s'", $foldertype));
97
-
98
-							// switch the foldertype for the next options
99
-							$spa->UseCPO($foldertype);
100
-
101
-							// set to synchronize all changes. The mobile could overwrite this value
102
-							$spa->SetFilterType(SYNC_FILTERTYPE_ALL);
103
-
104
-							if (!self::$decoder->getElementEndTag()) {
105
-								return false;
106
-							}
107
-						}
108
-						// if no foldertype is defined, use default cpo
109
-						elseif ($firstOption) {
110
-							$spa->UseCPO();
111
-							// set to synchronize all changes. The mobile could overwrite this value
112
-							$spa->SetFilterType(SYNC_FILTERTYPE_ALL);
113
-						}
114
-						$firstOption = false;
115
-
116
-						if (self::$decoder->getElementStartTag(SYNC_FILTERTYPE)) {
117
-							$spa->SetFilterType(self::$decoder->getElementContent());
118
-							if (!self::$decoder->getElementEndTag()) {
119
-								return false;
120
-							}
121
-						}
122
-
123
-						if (self::$decoder->getElementStartTag(SYNC_MAXITEMS)) {
124
-							$spa->SetWindowSize($maxitems = self::$decoder->getElementContent());
125
-							if (!self::$decoder->getElementEndTag()) {
126
-								return false;
127
-							}
128
-						}
129
-
130
-						$e = self::$decoder->peek();
131
-						if ($e[EN_TYPE] == EN_TYPE_ENDTAG) {
132
-							self::$decoder->getElementEndTag();
133
-
134
-							break;
135
-						}
136
-					}
137
-				}
138
-
139
-				$e = self::$decoder->peek();
140
-				if ($e[EN_TYPE] == EN_TYPE_ENDTAG) {
141
-					self::$decoder->getElementEndTag(); // SYNC_GETITEMESTIMATE_FOLDER
142
-
143
-					break;
144
-				}
145
-			}
146
-			// Process folder data
147
-
148
-			// In AS 14 request only collectionid is sent, without class
149
-			if (!$spa->HasContentClass() && $spa->HasFolderId()) {
150
-				try {
151
-					$spa->SetContentClass(self::$deviceManager->GetFolderClassFromCacheByID($spa->GetFolderId()));
152
-				}
153
-				catch (NoHierarchyCacheAvailableException $nhca) {
154
-					$spastatus = SYNC_GETITEMESTSTATUS_COLLECTIONINVALID;
155
-				}
156
-			}
157
-
158
-			// compatibility mode AS 1.0 - get folderid which was sent during GetHierarchy()
159
-			if (!$spa->HasFolderId() && $spa->HasContentClass()) {
160
-				$spa->SetFolderId(self::$deviceManager->GetFolderIdFromCacheByClass($spa->GetContentClass()));
161
-			}
162
-
163
-			// Add collection to SC and load state
164
-			$sc->AddCollection($spa);
165
-			if ($spastatus) {
166
-				// the CPO has a folder id now, so we can set the status
167
-				$sc->AddParameter($spa, "status", $spastatus);
168
-			}
169
-			else {
170
-				try {
171
-					$sc->AddParameter($spa, "state", self::$deviceManager->GetStateManager()->GetSyncState($spa->GetSyncKey()));
172
-
173
-					// if this is an additional folder the backend has to be setup correctly
174
-					if (!self::$backend->Setup(GSync::GetAdditionalSyncFolderStore($spa->GetBackendFolderId()))) {
175
-						throw new StatusException(sprintf("HandleGetItemEstimate() could not Setup() the backend for folder id %s/%s", $spa->GetFolderId(), $spa->GetBackendFolderId()), SYNC_GETITEMESTSTATUS_COLLECTIONINVALID);
176
-					}
177
-				}
178
-				catch (StateNotFoundException $snfex) {
179
-					// ok, the key is invalid. Question is, if the hierarchycache is still ok
180
-					// if not, we have to issue SYNC_GETITEMESTSTATUS_COLLECTIONINVALID which triggers a FolderSync
181
-					try {
182
-						self::$deviceManager->GetFolderClassFromCacheByID($spa->GetFolderId());
183
-						// we got here, so the HierarchyCache is ok
184
-						$sc->AddParameter($spa, "status", SYNC_GETITEMESTSTATUS_SYNCKKEYINVALID);
185
-					}
186
-					catch (NoHierarchyCacheAvailableException $nhca) {
187
-						$sc->AddParameter($spa, "status", SYNC_GETITEMESTSTATUS_COLLECTIONINVALID);
188
-					}
189
-
190
-					self::$topCollector->AnnounceInformation("StateNotFoundException " . $sc->GetParameter($spa, "status"), true);
191
-				}
192
-				catch (StatusException $stex) {
193
-					if ($stex->getCode() == SYNC_GETITEMESTSTATUS_COLLECTIONINVALID) {
194
-						$sc->AddParameter($spa, "status", SYNC_GETITEMESTSTATUS_COLLECTIONINVALID);
195
-					}
196
-					else {
197
-						$sc->AddParameter($spa, "status", SYNC_GETITEMESTSTATUS_SYNCSTATENOTPRIMED);
198
-					}
199
-					self::$topCollector->AnnounceInformation("StatusException " . $sc->GetParameter($spa, "status"), true);
200
-				}
201
-			}
202
-		}
203
-		if (!self::$decoder->getElementEndTag()) {
204
-			return false;
205
-		} // SYNC_GETITEMESTIMATE_FOLDERS
206
-
207
-		if (!self::$decoder->getElementEndTag()) {
208
-			return false;
209
-		} // SYNC_GETITEMESTIMATE_GETITEMESTIMATE
210
-
211
-		self::$encoder->startWBXML();
212
-		self::$encoder->startTag(SYNC_GETITEMESTIMATE_GETITEMESTIMATE);
213
-
214
-		$status = SYNC_GETITEMESTSTATUS_SUCCESS;
215
-		// look for changes in all collections
216
-
217
-		try {
218
-			$sc->CountChanges();
219
-		}
220
-		catch (StatusException $ste) {
221
-			$status = SYNC_GETITEMESTSTATUS_COLLECTIONINVALID;
222
-		}
223
-		$changes = $sc->GetChangedFolderIds();
224
-
225
-		foreach ($sc as $folderid => $spa) {
226
-			self::$encoder->startTag(SYNC_GETITEMESTIMATE_RESPONSE);
227
-
228
-			if ($sc->GetParameter($spa, "status")) {
229
-				$status = $sc->GetParameter($spa, "status");
230
-			}
231
-
232
-			self::$encoder->startTag(SYNC_GETITEMESTIMATE_STATUS);
233
-			self::$encoder->content($status);
234
-			self::$encoder->endTag();
235
-
236
-			self::$encoder->startTag(SYNC_GETITEMESTIMATE_FOLDER);
237
-
238
-			self::$encoder->startTag(SYNC_GETITEMESTIMATE_FOLDERTYPE);
239
-			self::$encoder->content($spa->GetContentClass());
240
-			self::$encoder->endTag();
241
-
242
-			self::$encoder->startTag(SYNC_GETITEMESTIMATE_FOLDERID);
243
-			self::$encoder->content($spa->GetFolderId());
244
-			self::$encoder->endTag();
245
-
246
-			if (isset($changes[$folderid]) && $changes[$folderid] !== false) {
247
-				self::$encoder->startTag(SYNC_GETITEMESTIMATE_ESTIMATE);
248
-				self::$encoder->content($changes[$folderid]);
249
-				self::$encoder->endTag();
250
-
251
-				if ($changes[$folderid] > 0) {
252
-					self::$topCollector->AnnounceInformation(sprintf("%s %d changes", $spa->GetContentClass(), $changes[$folderid]), true);
253
-				}
254
-
255
-				// update the device data to mark folders as complete when syncing with WM
256
-				if ($changes[$folderid] == 0) {
257
-					self::$deviceManager->SetFolderSyncStatus($folderid, DeviceManager::FLD_SYNC_COMPLETED);
258
-				}
259
-			}
260
-
261
-			self::$encoder->endTag();
262
-
263
-			self::$encoder->endTag();
264
-		}
265
-		if (array_sum($changes) == 0) {
266
-			self::$topCollector->AnnounceInformation("No changes found", true);
267
-		}
268
-
269
-		self::$encoder->endTag();
270
-
271
-		return true;
272
-	}
11
+    /**
12
+     * Handles the GetItemEstimate command
13
+     * Returns an estimation of how many items will be synchronized at the next sync
14
+     * This is mostly used to show something in the progress bar.
15
+     *
16
+     * @param int $commandCode
17
+     *
18
+     * @return bool
19
+     */
20
+    public function Handle($commandCode) {
21
+        $sc = new SyncCollections();
22
+
23
+        if (!self::$decoder->getElementStartTag(SYNC_GETITEMESTIMATE_GETITEMESTIMATE)) {
24
+            return false;
25
+        }
26
+
27
+        if (!self::$decoder->getElementStartTag(SYNC_GETITEMESTIMATE_FOLDERS)) {
28
+            return false;
29
+        }
30
+
31
+        while (self::$decoder->getElementStartTag(SYNC_GETITEMESTIMATE_FOLDER)) {
32
+            $spa = new SyncParameters();
33
+            $spastatus = false;
34
+
35
+            // read the folder properties
36
+            WBXMLDecoder::ResetInWhile("getItemEstimateFolders");
37
+            while (WBXMLDecoder::InWhile("getItemEstimateFolders")) {
38
+                if (self::$decoder->getElementStartTag(SYNC_SYNCKEY)) {
39
+                    try {
40
+                        $spa->SetSyncKey(self::$decoder->getElementContent());
41
+                    }
42
+                    catch (StateInvalidException $siex) {
43
+                        $spastatus = SYNC_GETITEMESTSTATUS_SYNCSTATENOTPRIMED;
44
+                    }
45
+
46
+                    if (!self::$decoder->getElementEndTag()) {
47
+                        return false;
48
+                    }
49
+                }
50
+                elseif (self::$decoder->getElementStartTag(SYNC_GETITEMESTIMATE_FOLDERID)) {
51
+                    $fid = self::$decoder->getElementContent();
52
+                    $spa->SetFolderId($fid);
53
+                    $spa->SetBackendFolderId(self::$deviceManager->GetBackendIdForFolderId($fid));
54
+
55
+                    if (!self::$decoder->getElementEndTag()) {
56
+                        return false;
57
+                    }
58
+                }
59
+
60
+                // conversation mode requested
61
+                elseif (self::$decoder->getElementStartTag(SYNC_CONVERSATIONMODE)) {
62
+                    $spa->SetConversationMode(true);
63
+                    if (($conversationmode = self::$decoder->getElementContent()) !== false) {
64
+                        $spa->SetConversationMode((bool) $conversationmode);
65
+                        if (!self::$decoder->getElementEndTag()) {
66
+                            return false;
67
+                        }
68
+                    }
69
+                }
70
+
71
+                // get items estimate does not necessarily send the folder type
72
+                elseif (self::$decoder->getElementStartTag(SYNC_GETITEMESTIMATE_FOLDERTYPE)) {
73
+                    $spa->SetContentClass(self::$decoder->getElementContent());
74
+
75
+                    if (!self::$decoder->getElementEndTag()) {
76
+                        return false;
77
+                    }
78
+                }
79
+
80
+                // TODO AS 2.5 and filtertype not set
81
+                elseif (self::$decoder->getElementStartTag(SYNC_FILTERTYPE)) {
82
+                    $spa->SetFilterType(self::$decoder->getElementContent());
83
+
84
+                    if (!self::$decoder->getElementEndTag()) {
85
+                        return false;
86
+                    }
87
+                }
88
+
89
+                while (self::$decoder->getElementStartTag(SYNC_OPTIONS)) {
90
+                    WBXMLDecoder::ResetInWhile("getItemEstimateOptions");
91
+                    while (WBXMLDecoder::InWhile("getItemEstimateOptions")) {
92
+                        $firstOption = true;
93
+                        // foldertype definition
94
+                        if (self::$decoder->getElementStartTag(SYNC_FOLDERTYPE)) {
95
+                            $foldertype = self::$decoder->getElementContent();
96
+                            SLog::Write(LOGLEVEL_DEBUG, sprintf("HandleGetItemEstimate(): specified options block with foldertype '%s'", $foldertype));
97
+
98
+                            // switch the foldertype for the next options
99
+                            $spa->UseCPO($foldertype);
100
+
101
+                            // set to synchronize all changes. The mobile could overwrite this value
102
+                            $spa->SetFilterType(SYNC_FILTERTYPE_ALL);
103
+
104
+                            if (!self::$decoder->getElementEndTag()) {
105
+                                return false;
106
+                            }
107
+                        }
108
+                        // if no foldertype is defined, use default cpo
109
+                        elseif ($firstOption) {
110
+                            $spa->UseCPO();
111
+                            // set to synchronize all changes. The mobile could overwrite this value
112
+                            $spa->SetFilterType(SYNC_FILTERTYPE_ALL);
113
+                        }
114
+                        $firstOption = false;
115
+
116
+                        if (self::$decoder->getElementStartTag(SYNC_FILTERTYPE)) {
117
+                            $spa->SetFilterType(self::$decoder->getElementContent());
118
+                            if (!self::$decoder->getElementEndTag()) {
119
+                                return false;
120
+                            }
121
+                        }
122
+
123
+                        if (self::$decoder->getElementStartTag(SYNC_MAXITEMS)) {
124
+                            $spa->SetWindowSize($maxitems = self::$decoder->getElementContent());
125
+                            if (!self::$decoder->getElementEndTag()) {
126
+                                return false;
127
+                            }
128
+                        }
129
+
130
+                        $e = self::$decoder->peek();
131
+                        if ($e[EN_TYPE] == EN_TYPE_ENDTAG) {
132
+                            self::$decoder->getElementEndTag();
133
+
134
+                            break;
135
+                        }
136
+                    }
137
+                }
138
+
139
+                $e = self::$decoder->peek();
140
+                if ($e[EN_TYPE] == EN_TYPE_ENDTAG) {
141
+                    self::$decoder->getElementEndTag(); // SYNC_GETITEMESTIMATE_FOLDER
142
+
143
+                    break;
144
+                }
145
+            }
146
+            // Process folder data
147
+
148
+            // In AS 14 request only collectionid is sent, without class
149
+            if (!$spa->HasContentClass() && $spa->HasFolderId()) {
150
+                try {
151
+                    $spa->SetContentClass(self::$deviceManager->GetFolderClassFromCacheByID($spa->GetFolderId()));
152
+                }
153
+                catch (NoHierarchyCacheAvailableException $nhca) {
154
+                    $spastatus = SYNC_GETITEMESTSTATUS_COLLECTIONINVALID;
155
+                }
156
+            }
157
+
158
+            // compatibility mode AS 1.0 - get folderid which was sent during GetHierarchy()
159
+            if (!$spa->HasFolderId() && $spa->HasContentClass()) {
160
+                $spa->SetFolderId(self::$deviceManager->GetFolderIdFromCacheByClass($spa->GetContentClass()));
161
+            }
162
+
163
+            // Add collection to SC and load state
164
+            $sc->AddCollection($spa);
165
+            if ($spastatus) {
166
+                // the CPO has a folder id now, so we can set the status
167
+                $sc->AddParameter($spa, "status", $spastatus);
168
+            }
169
+            else {
170
+                try {
171
+                    $sc->AddParameter($spa, "state", self::$deviceManager->GetStateManager()->GetSyncState($spa->GetSyncKey()));
172
+
173
+                    // if this is an additional folder the backend has to be setup correctly
174
+                    if (!self::$backend->Setup(GSync::GetAdditionalSyncFolderStore($spa->GetBackendFolderId()))) {
175
+                        throw new StatusException(sprintf("HandleGetItemEstimate() could not Setup() the backend for folder id %s/%s", $spa->GetFolderId(), $spa->GetBackendFolderId()), SYNC_GETITEMESTSTATUS_COLLECTIONINVALID);
176
+                    }
177
+                }
178
+                catch (StateNotFoundException $snfex) {
179
+                    // ok, the key is invalid. Question is, if the hierarchycache is still ok
180
+                    // if not, we have to issue SYNC_GETITEMESTSTATUS_COLLECTIONINVALID which triggers a FolderSync
181
+                    try {
182
+                        self::$deviceManager->GetFolderClassFromCacheByID($spa->GetFolderId());
183
+                        // we got here, so the HierarchyCache is ok
184
+                        $sc->AddParameter($spa, "status", SYNC_GETITEMESTSTATUS_SYNCKKEYINVALID);
185
+                    }
186
+                    catch (NoHierarchyCacheAvailableException $nhca) {
187
+                        $sc->AddParameter($spa, "status", SYNC_GETITEMESTSTATUS_COLLECTIONINVALID);
188
+                    }
189
+
190
+                    self::$topCollector->AnnounceInformation("StateNotFoundException " . $sc->GetParameter($spa, "status"), true);
191
+                }
192
+                catch (StatusException $stex) {
193
+                    if ($stex->getCode() == SYNC_GETITEMESTSTATUS_COLLECTIONINVALID) {
194
+                        $sc->AddParameter($spa, "status", SYNC_GETITEMESTSTATUS_COLLECTIONINVALID);
195
+                    }
196
+                    else {
197
+                        $sc->AddParameter($spa, "status", SYNC_GETITEMESTSTATUS_SYNCSTATENOTPRIMED);
198
+                    }
199
+                    self::$topCollector->AnnounceInformation("StatusException " . $sc->GetParameter($spa, "status"), true);
200
+                }
201
+            }
202
+        }
203
+        if (!self::$decoder->getElementEndTag()) {
204
+            return false;
205
+        } // SYNC_GETITEMESTIMATE_FOLDERS
206
+
207
+        if (!self::$decoder->getElementEndTag()) {
208
+            return false;
209
+        } // SYNC_GETITEMESTIMATE_GETITEMESTIMATE
210
+
211
+        self::$encoder->startWBXML();
212
+        self::$encoder->startTag(SYNC_GETITEMESTIMATE_GETITEMESTIMATE);
213
+
214
+        $status = SYNC_GETITEMESTSTATUS_SUCCESS;
215
+        // look for changes in all collections
216
+
217
+        try {
218
+            $sc->CountChanges();
219
+        }
220
+        catch (StatusException $ste) {
221
+            $status = SYNC_GETITEMESTSTATUS_COLLECTIONINVALID;
222
+        }
223
+        $changes = $sc->GetChangedFolderIds();
224
+
225
+        foreach ($sc as $folderid => $spa) {
226
+            self::$encoder->startTag(SYNC_GETITEMESTIMATE_RESPONSE);
227
+
228
+            if ($sc->GetParameter($spa, "status")) {
229
+                $status = $sc->GetParameter($spa, "status");
230
+            }
231
+
232
+            self::$encoder->startTag(SYNC_GETITEMESTIMATE_STATUS);
233
+            self::$encoder->content($status);
234
+            self::$encoder->endTag();
235
+
236
+            self::$encoder->startTag(SYNC_GETITEMESTIMATE_FOLDER);
237
+
238
+            self::$encoder->startTag(SYNC_GETITEMESTIMATE_FOLDERTYPE);
239
+            self::$encoder->content($spa->GetContentClass());
240
+            self::$encoder->endTag();
241
+
242
+            self::$encoder->startTag(SYNC_GETITEMESTIMATE_FOLDERID);
243
+            self::$encoder->content($spa->GetFolderId());
244
+            self::$encoder->endTag();
245
+
246
+            if (isset($changes[$folderid]) && $changes[$folderid] !== false) {
247
+                self::$encoder->startTag(SYNC_GETITEMESTIMATE_ESTIMATE);
248
+                self::$encoder->content($changes[$folderid]);
249
+                self::$encoder->endTag();
250
+
251
+                if ($changes[$folderid] > 0) {
252
+                    self::$topCollector->AnnounceInformation(sprintf("%s %d changes", $spa->GetContentClass(), $changes[$folderid]), true);
253
+                }
254
+
255
+                // update the device data to mark folders as complete when syncing with WM
256
+                if ($changes[$folderid] == 0) {
257
+                    self::$deviceManager->SetFolderSyncStatus($folderid, DeviceManager::FLD_SYNC_COMPLETED);
258
+                }
259
+            }
260
+
261
+            self::$encoder->endTag();
262
+
263
+            self::$encoder->endTag();
264
+        }
265
+        if (array_sum($changes) == 0) {
266
+            self::$topCollector->AnnounceInformation("No changes found", true);
267
+        }
268
+
269
+        self::$encoder->endTag();
270
+
271
+        return true;
272
+    }
273 273
 }
Please login to merge, or discard this patch.
Spacing   +3 added lines, -3 removed lines patch added patch discarded remove patch
@@ -61,7 +61,7 @@  discard block
 block discarded – undo
61 61
 				elseif (self::$decoder->getElementStartTag(SYNC_CONVERSATIONMODE)) {
62 62
 					$spa->SetConversationMode(true);
63 63
 					if (($conversationmode = self::$decoder->getElementContent()) !== false) {
64
-						$spa->SetConversationMode((bool) $conversationmode);
64
+						$spa->SetConversationMode((bool)$conversationmode);
65 65
 						if (!self::$decoder->getElementEndTag()) {
66 66
 							return false;
67 67
 						}
@@ -187,7 +187,7 @@  discard block
 block discarded – undo
187 187
 						$sc->AddParameter($spa, "status", SYNC_GETITEMESTSTATUS_COLLECTIONINVALID);
188 188
 					}
189 189
 
190
-					self::$topCollector->AnnounceInformation("StateNotFoundException " . $sc->GetParameter($spa, "status"), true);
190
+					self::$topCollector->AnnounceInformation("StateNotFoundException ".$sc->GetParameter($spa, "status"), true);
191 191
 				}
192 192
 				catch (StatusException $stex) {
193 193
 					if ($stex->getCode() == SYNC_GETITEMESTSTATUS_COLLECTIONINVALID) {
@@ -196,7 +196,7 @@  discard block
 block discarded – undo
196 196
 					else {
197 197
 						$sc->AddParameter($spa, "status", SYNC_GETITEMESTSTATUS_SYNCSTATENOTPRIMED);
198 198
 					}
199
-					self::$topCollector->AnnounceInformation("StatusException " . $sc->GetParameter($spa, "status"), true);
199
+					self::$topCollector->AnnounceInformation("StatusException ".$sc->GetParameter($spa, "status"), true);
200 200
 				}
201 201
 			}
202 202
 		}
Please login to merge, or discard this patch.
Braces   +9 added lines, -18 removed lines patch added patch discarded remove patch
@@ -38,16 +38,14 @@  discard block
 block discarded – undo
38 38
 				if (self::$decoder->getElementStartTag(SYNC_SYNCKEY)) {
39 39
 					try {
40 40
 						$spa->SetSyncKey(self::$decoder->getElementContent());
41
-					}
42
-					catch (StateInvalidException $siex) {
41
+					} catch (StateInvalidException $siex) {
43 42
 						$spastatus = SYNC_GETITEMESTSTATUS_SYNCSTATENOTPRIMED;
44 43
 					}
45 44
 
46 45
 					if (!self::$decoder->getElementEndTag()) {
47 46
 						return false;
48 47
 					}
49
-				}
50
-				elseif (self::$decoder->getElementStartTag(SYNC_GETITEMESTIMATE_FOLDERID)) {
48
+				} elseif (self::$decoder->getElementStartTag(SYNC_GETITEMESTIMATE_FOLDERID)) {
51 49
 					$fid = self::$decoder->getElementContent();
52 50
 					$spa->SetFolderId($fid);
53 51
 					$spa->SetBackendFolderId(self::$deviceManager->GetBackendIdForFolderId($fid));
@@ -149,8 +147,7 @@  discard block
 block discarded – undo
149 147
 			if (!$spa->HasContentClass() && $spa->HasFolderId()) {
150 148
 				try {
151 149
 					$spa->SetContentClass(self::$deviceManager->GetFolderClassFromCacheByID($spa->GetFolderId()));
152
-				}
153
-				catch (NoHierarchyCacheAvailableException $nhca) {
150
+				} catch (NoHierarchyCacheAvailableException $nhca) {
154 151
 					$spastatus = SYNC_GETITEMESTSTATUS_COLLECTIONINVALID;
155 152
 				}
156 153
 			}
@@ -165,8 +162,7 @@  discard block
 block discarded – undo
165 162
 			if ($spastatus) {
166 163
 				// the CPO has a folder id now, so we can set the status
167 164
 				$sc->AddParameter($spa, "status", $spastatus);
168
-			}
169
-			else {
165
+			} else {
170 166
 				try {
171 167
 					$sc->AddParameter($spa, "state", self::$deviceManager->GetStateManager()->GetSyncState($spa->GetSyncKey()));
172 168
 
@@ -174,26 +170,22 @@  discard block
 block discarded – undo
174 170
 					if (!self::$backend->Setup(GSync::GetAdditionalSyncFolderStore($spa->GetBackendFolderId()))) {
175 171
 						throw new StatusException(sprintf("HandleGetItemEstimate() could not Setup() the backend for folder id %s/%s", $spa->GetFolderId(), $spa->GetBackendFolderId()), SYNC_GETITEMESTSTATUS_COLLECTIONINVALID);
176 172
 					}
177
-				}
178
-				catch (StateNotFoundException $snfex) {
173
+				} catch (StateNotFoundException $snfex) {
179 174
 					// ok, the key is invalid. Question is, if the hierarchycache is still ok
180 175
 					// if not, we have to issue SYNC_GETITEMESTSTATUS_COLLECTIONINVALID which triggers a FolderSync
181 176
 					try {
182 177
 						self::$deviceManager->GetFolderClassFromCacheByID($spa->GetFolderId());
183 178
 						// we got here, so the HierarchyCache is ok
184 179
 						$sc->AddParameter($spa, "status", SYNC_GETITEMESTSTATUS_SYNCKKEYINVALID);
185
-					}
186
-					catch (NoHierarchyCacheAvailableException $nhca) {
180
+					} catch (NoHierarchyCacheAvailableException $nhca) {
187 181
 						$sc->AddParameter($spa, "status", SYNC_GETITEMESTSTATUS_COLLECTIONINVALID);
188 182
 					}
189 183
 
190 184
 					self::$topCollector->AnnounceInformation("StateNotFoundException " . $sc->GetParameter($spa, "status"), true);
191
-				}
192
-				catch (StatusException $stex) {
185
+				} catch (StatusException $stex) {
193 186
 					if ($stex->getCode() == SYNC_GETITEMESTSTATUS_COLLECTIONINVALID) {
194 187
 						$sc->AddParameter($spa, "status", SYNC_GETITEMESTSTATUS_COLLECTIONINVALID);
195
-					}
196
-					else {
188
+					} else {
197 189
 						$sc->AddParameter($spa, "status", SYNC_GETITEMESTSTATUS_SYNCSTATENOTPRIMED);
198 190
 					}
199 191
 					self::$topCollector->AnnounceInformation("StatusException " . $sc->GetParameter($spa, "status"), true);
@@ -216,8 +208,7 @@  discard block
 block discarded – undo
216 208
 
217 209
 		try {
218 210
 			$sc->CountChanges();
219
-		}
220
-		catch (StatusException $ste) {
211
+		} catch (StatusException $ste) {
221 212
 			$status = SYNC_GETITEMESTSTATUS_COLLECTIONINVALID;
222 213
 		}
223 214
 		$changes = $sc->GetChangedFolderIds();
Please login to merge, or discard this patch.
lib/request/resolverecipients.php 1 patch
Indentation   +49 added lines, -49 removed lines patch added patch discarded remove patch
@@ -8,64 +8,64 @@
 block discarded – undo
8 8
  */
9 9
 
10 10
 class ResolveRecipients extends RequestProcessor {
11
-	/**
12
-	 * Handles the ResolveRecipients command.
13
-	 *
14
-	 * @param int $commandCode
15
-	 *
16
-	 * @return bool
17
-	 */
18
-	public function Handle($commandCode) {
19
-		// Parse input
20
-		if (!self::$decoder->getElementStartTag(SYNC_RESOLVERECIPIENTS_RESOLVERECIPIENTS)) {
21
-			return false;
22
-		}
11
+    /**
12
+     * Handles the ResolveRecipients command.
13
+     *
14
+     * @param int $commandCode
15
+     *
16
+     * @return bool
17
+     */
18
+    public function Handle($commandCode) {
19
+        // Parse input
20
+        if (!self::$decoder->getElementStartTag(SYNC_RESOLVERECIPIENTS_RESOLVERECIPIENTS)) {
21
+            return false;
22
+        }
23 23
 
24
-		$resolveRecipients = new SyncResolveRecipients();
25
-		$resolveRecipients->Decode(self::$decoder);
24
+        $resolveRecipients = new SyncResolveRecipients();
25
+        $resolveRecipients->Decode(self::$decoder);
26 26
 
27
-		if (!self::$decoder->getElementEndTag()) {
28
-			return false;
29
-		} // SYNC_RESOLVERECIPIENTS_RESOLVERECIPIENTS
27
+        if (!self::$decoder->getElementEndTag()) {
28
+            return false;
29
+        } // SYNC_RESOLVERECIPIENTS_RESOLVERECIPIENTS
30 30
 
31
-		$resolveRecipients = self::$backend->ResolveRecipients($resolveRecipients);
31
+        $resolveRecipients = self::$backend->ResolveRecipients($resolveRecipients);
32 32
 
33
-		self::$encoder->startWBXML();
34
-		self::$encoder->startTag(SYNC_RESOLVERECIPIENTS_RESOLVERECIPIENTS);
33
+        self::$encoder->startWBXML();
34
+        self::$encoder->startTag(SYNC_RESOLVERECIPIENTS_RESOLVERECIPIENTS);
35 35
 
36
-		self::$encoder->startTag(SYNC_RESOLVERECIPIENTS_STATUS);
37
-		self::$encoder->content($resolveRecipients->status);
38
-		self::$encoder->endTag(); // SYNC_RESOLVERECIPIENTS_STATUS
36
+        self::$encoder->startTag(SYNC_RESOLVERECIPIENTS_STATUS);
37
+        self::$encoder->content($resolveRecipients->status);
38
+        self::$encoder->endTag(); // SYNC_RESOLVERECIPIENTS_STATUS
39 39
 
40
-		if ($resolveRecipients->status == SYNC_COMMONSTATUS_SUCCESS && !empty($resolveRecipients->response)) {
41
-			foreach ($resolveRecipients->response as $i => $response) {
42
-				self::$encoder->startTag(SYNC_RESOLVERECIPIENTS_RESPONSE);
43
-				self::$encoder->startTag(SYNC_RESOLVERECIPIENTS_TO);
44
-				self::$encoder->content($response->to);
45
-				self::$encoder->endTag(); // SYNC_RESOLVERECIPIENTS_TO
40
+        if ($resolveRecipients->status == SYNC_COMMONSTATUS_SUCCESS && !empty($resolveRecipients->response)) {
41
+            foreach ($resolveRecipients->response as $i => $response) {
42
+                self::$encoder->startTag(SYNC_RESOLVERECIPIENTS_RESPONSE);
43
+                self::$encoder->startTag(SYNC_RESOLVERECIPIENTS_TO);
44
+                self::$encoder->content($response->to);
45
+                self::$encoder->endTag(); // SYNC_RESOLVERECIPIENTS_TO
46 46
 
47
-				self::$encoder->startTag(SYNC_RESOLVERECIPIENTS_STATUS);
48
-				self::$encoder->content($response->status);
49
-				self::$encoder->endTag(); // SYNC_RESOLVERECIPIENTS_STATUS
47
+                self::$encoder->startTag(SYNC_RESOLVERECIPIENTS_STATUS);
48
+                self::$encoder->content($response->status);
49
+                self::$encoder->endTag(); // SYNC_RESOLVERECIPIENTS_STATUS
50 50
 
51
-				// do only if recipient is resolved
52
-				if ($response->status != SYNC_RESOLVERECIPSSTATUS_RESPONSE_UNRESOLVEDRECIP && !empty($response->recipient)) {
53
-					self::$encoder->startTag(SYNC_RESOLVERECIPIENTS_RECIPIENTCOUNT);
54
-					self::$encoder->content(count($response->recipient));
55
-					self::$encoder->endTag(); // SYNC_RESOLVERECIPIENTS_RECIPIENTCOUNT
51
+                // do only if recipient is resolved
52
+                if ($response->status != SYNC_RESOLVERECIPSSTATUS_RESPONSE_UNRESOLVEDRECIP && !empty($response->recipient)) {
53
+                    self::$encoder->startTag(SYNC_RESOLVERECIPIENTS_RECIPIENTCOUNT);
54
+                    self::$encoder->content(count($response->recipient));
55
+                    self::$encoder->endTag(); // SYNC_RESOLVERECIPIENTS_RECIPIENTCOUNT
56 56
 
57
-					foreach ($response->recipient as $recipient) {
58
-						self::$encoder->startTag(SYNC_RESOLVERECIPIENTS_RECIPIENT);
59
-						$recipient->Encode(self::$encoder);
60
-						self::$encoder->endTag(); // SYNC_RESOLVERECIPIENTS_RECIPIENT
61
-					}
62
-				}
63
-				self::$encoder->endTag(); // SYNC_RESOLVERECIPIENTS_RESPONSE
64
-			}
65
-		}
57
+                    foreach ($response->recipient as $recipient) {
58
+                        self::$encoder->startTag(SYNC_RESOLVERECIPIENTS_RECIPIENT);
59
+                        $recipient->Encode(self::$encoder);
60
+                        self::$encoder->endTag(); // SYNC_RESOLVERECIPIENTS_RECIPIENT
61
+                    }
62
+                }
63
+                self::$encoder->endTag(); // SYNC_RESOLVERECIPIENTS_RESPONSE
64
+            }
65
+        }
66 66
 
67
-		self::$encoder->endTag(); // SYNC_RESOLVERECIPIENTS_RESOLVERECIPIENTS
67
+        self::$encoder->endTag(); // SYNC_RESOLVERECIPIENTS_RESOLVERECIPIENTS
68 68
 
69
-		return true;
70
-	}
69
+        return true;
70
+    }
71 71
 }
Please login to merge, or discard this patch.
lib/request/search.php 2 patches
Indentation   +508 added lines, -508 removed lines patch added patch discarded remove patch
@@ -8,512 +8,512 @@
 block discarded – undo
8 8
  */
9 9
 
10 10
 class Search extends RequestProcessor {
11
-	/**
12
-	 * Handles the Search command.
13
-	 *
14
-	 * @param int $commandCode
15
-	 *
16
-	 * @return bool
17
-	 */
18
-	public function Handle($commandCode) {
19
-		$searchrange = '0';
20
-		$searchpicture = false;
21
-		$cpo = new ContentParameters();
22
-
23
-		if (!self::$decoder->getElementStartTag(SYNC_SEARCH_SEARCH)) {
24
-			return false;
25
-		}
26
-
27
-		// TODO check: possible to search in other stores?
28
-		if (!self::$decoder->getElementStartTag(SYNC_SEARCH_STORE)) {
29
-			return false;
30
-		}
31
-
32
-		if (!self::$decoder->getElementStartTag(SYNC_SEARCH_NAME)) {
33
-			return false;
34
-		}
35
-		$searchname = strtoupper(self::$decoder->getElementContent());
36
-		if (!self::$decoder->getElementEndTag()) {
37
-			return false;
38
-		}
39
-
40
-		if (!self::$decoder->getElementStartTag(SYNC_SEARCH_QUERY)) {
41
-			return false;
42
-		}
43
-
44
-		// check if it is a content of an element (= GAL search)
45
-		// or a starttag (= mailbox or documentlibrary search)
46
-		$searchquery = self::$decoder->getElementContent();
47
-		if ($searchquery && !self::$decoder->getElementEndTag()) {
48
-			return false;
49
-		}
50
-
51
-		if ($searchquery === false) {
52
-			$cpo->SetSearchName($searchname);
53
-			if (self::$decoder->getElementStartTag(SYNC_SEARCH_AND)) {
54
-				if (self::$decoder->getElementStartTag(SYNC_FOLDERID)) {
55
-					$searchfolderid = self::$decoder->getElementContent();
56
-					$cpo->SetSearchFolderid($searchfolderid);
57
-					if (!self::$decoder->getElementEndTag()) { // SYNC_FOLDERTYPE
58
-						return false;
59
-					}
60
-				}
61
-
62
-				if (self::$decoder->getElementStartTag(SYNC_FOLDERTYPE)) {
63
-					$searchclass = self::$decoder->getElementContent();
64
-					$cpo->SetSearchClass($searchclass);
65
-					if (!self::$decoder->getElementEndTag()) { // SYNC_FOLDERTYPE
66
-						return false;
67
-					}
68
-				}
69
-
70
-				if (self::$decoder->getElementStartTag(SYNC_FOLDERID)) {
71
-					$searchfolderid = self::$decoder->getElementContent();
72
-					$cpo->SetSearchFolderid($searchfolderid);
73
-					if (!self::$decoder->getElementEndTag()) { // SYNC_FOLDERTYPE
74
-						return false;
75
-					}
76
-				}
77
-
78
-				if (self::$decoder->getElementStartTag(SYNC_SEARCH_FREETEXT)) {
79
-					$searchfreetext = self::$decoder->getElementContent();
80
-					$cpo->SetSearchFreeText($searchfreetext);
81
-					if (!self::$decoder->getElementEndTag()) { // SYNC_SEARCH_FREETEXT
82
-						return false;
83
-					}
84
-				}
85
-
86
-				// TODO - review
87
-				if (self::$decoder->getElementStartTag(SYNC_SEARCH_GREATERTHAN)) {
88
-					if (self::$decoder->getElementStartTag(SYNC_POOMMAIL_DATERECEIVED)) {
89
-						$datereceivedgreater = true;
90
-						if (($dam = self::$decoder->getElementContent()) !== false) {
91
-							$datereceivedgreater = true;
92
-							if (!self::$decoder->getElementEndTag()) {
93
-								return false;
94
-							}
95
-						}
96
-						$cpo->SetSearchDateReceivedGreater($datereceivedgreater);
97
-					}
98
-
99
-					if (self::$decoder->getElementStartTag(SYNC_SEARCH_VALUE)) {
100
-						$searchvalue = self::$decoder->getElementContent();
101
-						$cpo->SetSearchValueGreater($searchvalue);
102
-						if (!self::$decoder->getElementEndTag()) { // SYNC_SEARCH_VALUE
103
-							return false;
104
-						}
105
-					}
106
-
107
-					if (!self::$decoder->getElementEndTag()) { // SYNC_SEARCH_GREATERTHAN
108
-						return false;
109
-					}
110
-				}
111
-
112
-				if (self::$decoder->getElementStartTag(SYNC_SEARCH_LESSTHAN)) {
113
-					if (self::$decoder->getElementStartTag(SYNC_POOMMAIL_DATERECEIVED)) {
114
-						$datereceivedless = true;
115
-						if (($dam = self::$decoder->getElementContent()) !== false) {
116
-							$datereceivedless = true;
117
-							if (!self::$decoder->getElementEndTag()) {
118
-								return false;
119
-							}
120
-						}
121
-						$cpo->SetSearchDateReceivedLess($datereceivedless);
122
-					}
123
-
124
-					if (self::$decoder->getElementStartTag(SYNC_SEARCH_VALUE)) {
125
-						$searchvalue = self::$decoder->getElementContent();
126
-						$cpo->SetSearchValueLess($searchvalue);
127
-						if (!self::$decoder->getElementEndTag()) { // SYNC_SEARCH_VALUE
128
-							return false;
129
-						}
130
-					}
131
-
132
-					if (!self::$decoder->getElementEndTag()) { // SYNC_SEARCH_LESSTHAN
133
-						return false;
134
-					}
135
-				}
136
-
137
-				if (self::$decoder->getElementStartTag(SYNC_SEARCH_FREETEXT)) {
138
-					$searchfreetext = self::$decoder->getElementContent();
139
-					$cpo->SetSearchFreeText($searchfreetext);
140
-					if (!self::$decoder->getElementEndTag()) { // SYNC_SEARCH_FREETEXT
141
-						return false;
142
-					}
143
-				}
144
-
145
-				if (!self::$decoder->getElementEndTag()) { // SYNC_SEARCH_AND
146
-					return false;
147
-				}
148
-			}
149
-			elseif (self::$decoder->getElementStartTag(SYNC_SEARCH_EQUALTO)) {
150
-				// linkid can be an empty tag as well as have value
151
-				if (self::$decoder->getElementStartTag(SYNC_DOCUMENTLIBRARY_LINKID)) {
152
-					if (($linkId = self::$decoder->getElementContent()) !== false) {
153
-						$cpo->SetLinkId($linkId);
154
-						if (!self::$decoder->getElementEndTag()) { // SYNC_DOCUMENTLIBRARY_LINKID
155
-							return false;
156
-						}
157
-					}
158
-				}
159
-
160
-				if (self::$decoder->getElementStartTag(SYNC_SEARCH_VALUE)) {
161
-					$searchvalue = self::$decoder->getElementContent();
162
-					$cpo->SetSearchValueEqualTo($searchvalue);
163
-					if (!self::$decoder->getElementEndTag()) { // SYNC_SEARCH_VALUE
164
-						return false;
165
-					}
166
-				}
167
-
168
-				if (!self::$decoder->getElementEndTag()) { // SYNC_SEARCH_EQUALTO
169
-					return false;
170
-				}
171
-			}
172
-
173
-			if (!self::$decoder->getElementEndTag()) { // SYNC_SEARCH_QUERY
174
-				return false;
175
-			}
176
-		}
177
-
178
-		if (self::$decoder->getElementStartTag(SYNC_SEARCH_OPTIONS)) {
179
-			WBXMLDecoder::ResetInWhile("searchOptions");
180
-			while (WBXMLDecoder::InWhile("searchOptions")) {
181
-				if (self::$decoder->getElementStartTag(SYNC_SEARCH_RANGE)) {
182
-					$searchrange = self::$decoder->getElementContent();
183
-					$cpo->SetSearchRange($searchrange);
184
-					if (!self::$decoder->getElementEndTag()) {
185
-						return false;
186
-					}
187
-				}
188
-
189
-				if (self::$decoder->getElementStartTag(SYNC_SEARCH_REBUILDRESULTS)) {
190
-					$rebuildresults = true;
191
-					if (($dam = self::$decoder->getElementContent()) !== false) {
192
-						$rebuildresults = true;
193
-						if (!self::$decoder->getElementEndTag()) {
194
-							return false;
195
-						}
196
-					}
197
-					$cpo->SetSearchRebuildResults($rebuildresults);
198
-				}
199
-
200
-				if (self::$decoder->getElementStartTag(SYNC_SEARCH_DEEPTRAVERSAL)) {
201
-					$deeptraversal = true;
202
-					if (($dam = self::$decoder->getElementContent()) !== false) {
203
-						$deeptraversal = true;
204
-						if (!self::$decoder->getElementEndTag()) {
205
-							return false;
206
-						}
207
-					}
208
-					$cpo->SetSearchDeepTraversal($deeptraversal);
209
-				}
210
-
211
-				if (self::$decoder->getElementStartTag(SYNC_MIMESUPPORT)) {
212
-					$cpo->SetMimeSupport(self::$decoder->getElementContent());
213
-					if (!self::$decoder->getElementEndTag()) {
214
-						return false;
215
-					}
216
-				}
217
-
218
-				// TODO body preferences
219
-				while (self::$decoder->getElementStartTag(SYNC_AIRSYNCBASE_BODYPREFERENCE)) {
220
-					if (self::$decoder->getElementStartTag(SYNC_AIRSYNCBASE_TYPE)) {
221
-						$bptype = self::$decoder->getElementContent();
222
-						$cpo->BodyPreference($bptype);
223
-						if (!self::$decoder->getElementEndTag()) {
224
-							return false;
225
-						}
226
-					}
227
-
228
-					if (self::$decoder->getElementStartTag(SYNC_AIRSYNCBASE_TRUNCATIONSIZE)) {
229
-						$cpo->BodyPreference($bptype)->SetTruncationSize(self::$decoder->getElementContent());
230
-						if (!self::$decoder->getElementEndTag()) {
231
-							return false;
232
-						}
233
-					}
234
-
235
-					if (self::$decoder->getElementStartTag(SYNC_AIRSYNCBASE_ALLORNONE)) {
236
-						$cpo->BodyPreference($bptype)->SetAllOrNone(self::$decoder->getElementContent());
237
-						if (!self::$decoder->getElementEndTag()) {
238
-							return false;
239
-						}
240
-					}
241
-
242
-					if (self::$decoder->getElementStartTag(SYNC_AIRSYNCBASE_PREVIEW)) {
243
-						$cpo->BodyPreference($bptype)->SetPreview(self::$decoder->getElementContent());
244
-						if (!self::$decoder->getElementEndTag()) {
245
-							return false;
246
-						}
247
-					}
248
-
249
-					if (!self::$decoder->getElementEndTag()) {
250
-						return false;
251
-					}
252
-				}
253
-
254
-				if (self::$decoder->getElementStartTag(SYNC_AIRSYNCBASE_BODYPARTPREFERENCE)) {
255
-					if (self::$decoder->getElementStartTag(SYNC_AIRSYNCBASE_TYPE)) {
256
-						$bpptype = self::$decoder->getElementContent();
257
-						$cpo->BodyPartPreference($bpptype);
258
-						if (!self::$decoder->getElementEndTag()) {
259
-							return false;
260
-						}
261
-					}
262
-
263
-					if (self::$decoder->getElementStartTag(SYNC_AIRSYNCBASE_TRUNCATIONSIZE)) {
264
-						$cpo->BodyPartPreference($bpptype)->SetTruncationSize(self::$decoder->getElementContent());
265
-						if (!self::$decoder->getElementEndTag()) {
266
-							return false;
267
-						}
268
-					}
269
-
270
-					if (self::$decoder->getElementStartTag(SYNC_AIRSYNCBASE_ALLORNONE)) {
271
-						$cpo->BodyPartPreference($bpptype)->SetAllOrNone(self::$decoder->getElementContent());
272
-						if (!self::$decoder->getElementEndTag()) {
273
-							return false;
274
-						}
275
-					}
276
-
277
-					if (self::$decoder->getElementStartTag(SYNC_AIRSYNCBASE_PREVIEW)) {
278
-						$cpo->BodyPartPreference($bpptype)->SetPreview(self::$decoder->getElementContent());
279
-						if (!self::$decoder->getElementEndTag()) {
280
-							return false;
281
-						}
282
-					}
283
-
284
-					if (!self::$decoder->getElementEndTag()) {
285
-						return false;
286
-					}
287
-				}
288
-
289
-				if (self::$decoder->getElementStartTag(SYNC_RIGHTSMANAGEMENT_SUPPORT)) {
290
-					$cpo->SetRmSupport(self::$decoder->getElementContent());
291
-					if (!self::$decoder->getElementEndTag()) {
292
-						return false;
293
-					}
294
-				}
295
-
296
-				if (self::$decoder->getElementStartTag(SYNC_SEARCH_PICTURE)) { // TODO - do something with maxsize and maxpictures in the backend
297
-					$searchpicture = new SyncResolveRecipientsPicture();
298
-					if (self::$decoder->getElementStartTag(SYNC_SEARCH_MAXSIZE)) {
299
-						$searchpicture->maxsize = self::$decoder->getElementContent();
300
-						if (!self::$decoder->getElementEndTag()) {
301
-							return false;
302
-						}
303
-					}
304
-
305
-					if (self::$decoder->getElementStartTag(SYNC_SEARCH_MAXPICTURES)) {
306
-						$searchpicture->maxpictures = self::$decoder->getElementContent();
307
-						if (!self::$decoder->getElementEndTag()) {
308
-							return false;
309
-						}
310
-					}
311
-
312
-					// iOs devices send empty picture tag: <Search:Picture/>
313
-					if (($sp = self::$decoder->getElementContent()) !== false) {
314
-						if (!self::$decoder->getElementEndTag()) {
315
-							return false;
316
-						}
317
-					}
318
-				}
319
-
320
-				$e = self::$decoder->peek();
321
-				if ($e[EN_TYPE] == EN_TYPE_ENDTAG) {
322
-					self::$decoder->getElementEndTag();
323
-
324
-					break;
325
-				}
326
-			}
327
-		}
328
-		if (!self::$decoder->getElementEndTag()) { // store
329
-			return false;
330
-		}
331
-
332
-		if (!self::$decoder->getElementEndTag()) { // search
333
-			return false;
334
-		}
335
-
336
-		// get SearchProvider
337
-		$searchprovider = GSync::GetBackend()->GetSearchProvider();
338
-		$status = SYNC_SEARCHSTATUS_SUCCESS;
339
-		$rows = [];
340
-
341
-		// TODO support other searches
342
-		if ($searchprovider->SupportsType($searchname)) {
343
-			$storestatus = SYNC_SEARCHSTATUS_STORE_SUCCESS;
344
-
345
-			try {
346
-				if ($searchname == ISearchProvider::SEARCH_GAL) {
347
-					// get search results from the searchprovider
348
-					$rows = $searchprovider->GetGALSearchResults($searchquery, $searchrange, $searchpicture);
349
-				}
350
-				elseif ($searchname == ISearchProvider::SEARCH_MAILBOX) {
351
-					$backendFolderId = self::$deviceManager->GetBackendIdForFolderId($cpo->GetSearchFolderid());
352
-					$cpo->SetSearchFolderid($backendFolderId);
353
-					$rows = $searchprovider->GetMailboxSearchResults($cpo);
354
-				}
355
-			}
356
-			catch (StatusException $stex) {
357
-				$storestatus = $stex->getCode();
358
-			}
359
-		}
360
-		else {
361
-			$rows = ['searchtotal' => 0];
362
-			$status = SYNC_SEARCHSTATUS_SERVERERROR;
363
-			SLog::Write(LOGLEVEL_WARN, sprintf("Searchtype '%s' is not supported.", $searchname));
364
-			self::$topCollector->AnnounceInformation(sprintf("Unsupported type '%s''", $searchname), true);
365
-		}
366
-		$searchprovider->Disconnect();
367
-
368
-		self::$topCollector->AnnounceInformation(sprintf("'%s' search found %d results", $searchname, (isset($rows['searchtotal']) ? $rows['searchtotal'] : 0)), true);
369
-
370
-		self::$encoder->startWBXML();
371
-		self::$encoder->startTag(SYNC_SEARCH_SEARCH);
372
-
373
-		self::$encoder->startTag(SYNC_SEARCH_STATUS);
374
-		self::$encoder->content($status);
375
-		self::$encoder->endTag();
376
-
377
-		if ($status == SYNC_SEARCHSTATUS_SUCCESS) {
378
-			self::$encoder->startTag(SYNC_SEARCH_RESPONSE);
379
-			self::$encoder->startTag(SYNC_SEARCH_STORE);
380
-
381
-			self::$encoder->startTag(SYNC_SEARCH_STATUS);
382
-			self::$encoder->content($storestatus);
383
-			self::$encoder->endTag();
384
-
385
-			if (isset($rows['range'])) {
386
-				$searchrange = $rows['range'];
387
-				unset($rows['range']);
388
-			}
389
-			if (isset($rows['searchtotal'])) {
390
-				$searchtotal = $rows['searchtotal'];
391
-				unset($rows['searchtotal']);
392
-			}
393
-			if ($searchname == ISearchProvider::SEARCH_GAL) {
394
-				if (is_array($rows) && !empty($rows)) {
395
-					foreach ($rows as $u) {
396
-						self::$encoder->startTag(SYNC_SEARCH_RESULT);
397
-						self::$encoder->startTag(SYNC_SEARCH_PROPERTIES);
398
-
399
-						self::$encoder->startTag(SYNC_GAL_DISPLAYNAME);
400
-						self::$encoder->content((isset($u[SYNC_GAL_DISPLAYNAME])) ? $u[SYNC_GAL_DISPLAYNAME] : "No name");
401
-						self::$encoder->endTag();
402
-
403
-						if (isset($u[SYNC_GAL_PHONE])) {
404
-							self::$encoder->startTag(SYNC_GAL_PHONE);
405
-							self::$encoder->content($u[SYNC_GAL_PHONE]);
406
-							self::$encoder->endTag();
407
-						}
408
-
409
-						if (isset($u[SYNC_GAL_OFFICE])) {
410
-							self::$encoder->startTag(SYNC_GAL_OFFICE);
411
-							self::$encoder->content($u[SYNC_GAL_OFFICE]);
412
-							self::$encoder->endTag();
413
-						}
414
-
415
-						if (isset($u[SYNC_GAL_TITLE])) {
416
-							self::$encoder->startTag(SYNC_GAL_TITLE);
417
-							self::$encoder->content($u[SYNC_GAL_TITLE]);
418
-							self::$encoder->endTag();
419
-						}
420
-
421
-						if (isset($u[SYNC_GAL_COMPANY])) {
422
-							self::$encoder->startTag(SYNC_GAL_COMPANY);
423
-							self::$encoder->content($u[SYNC_GAL_COMPANY]);
424
-							self::$encoder->endTag();
425
-						}
426
-
427
-						if (isset($u[SYNC_GAL_ALIAS])) {
428
-							self::$encoder->startTag(SYNC_GAL_ALIAS);
429
-							self::$encoder->content($u[SYNC_GAL_ALIAS]);
430
-							self::$encoder->endTag();
431
-						}
432
-
433
-						// Always send the firstname, even empty. Nokia needs this to display the entry
434
-						self::$encoder->startTag(SYNC_GAL_FIRSTNAME);
435
-						self::$encoder->content((isset($u[SYNC_GAL_FIRSTNAME])) ? $u[SYNC_GAL_FIRSTNAME] : "");
436
-						self::$encoder->endTag();
437
-
438
-						self::$encoder->startTag(SYNC_GAL_LASTNAME);
439
-						self::$encoder->content((isset($u[SYNC_GAL_LASTNAME])) ? $u[SYNC_GAL_LASTNAME] : "No name");
440
-						self::$encoder->endTag();
441
-
442
-						if (isset($u[SYNC_GAL_HOMEPHONE])) {
443
-							self::$encoder->startTag(SYNC_GAL_HOMEPHONE);
444
-							self::$encoder->content($u[SYNC_GAL_HOMEPHONE]);
445
-							self::$encoder->endTag();
446
-						}
447
-
448
-						if (isset($u[SYNC_GAL_MOBILEPHONE])) {
449
-							self::$encoder->startTag(SYNC_GAL_MOBILEPHONE);
450
-							self::$encoder->content($u[SYNC_GAL_MOBILEPHONE]);
451
-							self::$encoder->endTag();
452
-						}
453
-
454
-						self::$encoder->startTag(SYNC_GAL_EMAILADDRESS);
455
-						self::$encoder->content((isset($u[SYNC_GAL_EMAILADDRESS])) ? $u[SYNC_GAL_EMAILADDRESS] : "");
456
-						self::$encoder->endTag();
457
-
458
-						if (isset($u[SYNC_GAL_PICTURE])) {
459
-							self::$encoder->startTag(SYNC_GAL_PICTURE);
460
-							self::$encoder->startTag(SYNC_GAL_STATUS);
461
-							self::$encoder->content(SYNC_SEARCHSTATUS_PICTURE_SUCCESS); // FIXME: status code
462
-												self::$encoder->endTag(); // SYNC_SEARCH_STATUS
463
-
464
-												self::$encoder->startTag(SYNC_GAL_DATA);
465
-							self::$encoder->contentStream($u[SYNC_GAL_PICTURE], false, true);
466
-							self::$encoder->endTag(); // SYNC_GAL_DATA
467
-											self::$encoder->endTag(); // SYNC_GAL_PICTURE
468
-						}
469
-
470
-						self::$encoder->endTag(); // result
471
-								self::$encoder->endTag(); // properties
472
-					}
473
-				}
474
-			}
475
-			elseif ($searchname == ISearchProvider::SEARCH_MAILBOX) {
476
-				foreach ($rows as $u) {
477
-					// TODO: unclear if any clients *require* the folder id where the message is located (it's not available anymore)
478
-					// $folderid = self::$deviceManager->GetFolderIdForBackendId($u['folderid']);
479
-
480
-					self::$encoder->startTag(SYNC_SEARCH_RESULT);
481
-					self::$encoder->startTag(SYNC_FOLDERTYPE);
482
-					self::$encoder->content($u['class']);
483
-					self::$encoder->endTag();
484
-					self::$encoder->startTag(SYNC_SEARCH_LONGID);
485
-					self::$encoder->content($u['longid']);
486
-					self::$encoder->endTag();
487
-					// self::$encoder->startTag(SYNC_FOLDERID);
488
-					// self::$encoder->content($folderid);
489
-					// self::$encoder->endTag();
490
-
491
-					self::$encoder->startTag(SYNC_SEARCH_PROPERTIES);
492
-					$message = self::$backend->Fetch(false, $u['longid'], $cpo);
493
-					$message->Encode(self::$encoder);
494
-
495
-					self::$encoder->endTag(); // result
496
-							self::$encoder->endTag(); // properties
497
-				}
498
-			}
499
-			// it seems that android 4 requires range and searchtotal
500
-			// or it won't display the search results
501
-			if (isset($searchrange)) {
502
-				self::$encoder->startTag(SYNC_SEARCH_RANGE);
503
-				self::$encoder->content($searchrange);
504
-				self::$encoder->endTag();
505
-			}
506
-			if (isset($searchtotal) && $searchtotal > 0) {
507
-				self::$encoder->startTag(SYNC_SEARCH_TOTAL);
508
-				self::$encoder->content($searchtotal);
509
-				self::$encoder->endTag();
510
-			}
511
-
512
-			self::$encoder->endTag(); // store
513
-				self::$encoder->endTag(); // response
514
-		}
515
-		self::$encoder->endTag(); // search
516
-
517
-		return true;
518
-	}
11
+    /**
12
+     * Handles the Search command.
13
+     *
14
+     * @param int $commandCode
15
+     *
16
+     * @return bool
17
+     */
18
+    public function Handle($commandCode) {
19
+        $searchrange = '0';
20
+        $searchpicture = false;
21
+        $cpo = new ContentParameters();
22
+
23
+        if (!self::$decoder->getElementStartTag(SYNC_SEARCH_SEARCH)) {
24
+            return false;
25
+        }
26
+
27
+        // TODO check: possible to search in other stores?
28
+        if (!self::$decoder->getElementStartTag(SYNC_SEARCH_STORE)) {
29
+            return false;
30
+        }
31
+
32
+        if (!self::$decoder->getElementStartTag(SYNC_SEARCH_NAME)) {
33
+            return false;
34
+        }
35
+        $searchname = strtoupper(self::$decoder->getElementContent());
36
+        if (!self::$decoder->getElementEndTag()) {
37
+            return false;
38
+        }
39
+
40
+        if (!self::$decoder->getElementStartTag(SYNC_SEARCH_QUERY)) {
41
+            return false;
42
+        }
43
+
44
+        // check if it is a content of an element (= GAL search)
45
+        // or a starttag (= mailbox or documentlibrary search)
46
+        $searchquery = self::$decoder->getElementContent();
47
+        if ($searchquery && !self::$decoder->getElementEndTag()) {
48
+            return false;
49
+        }
50
+
51
+        if ($searchquery === false) {
52
+            $cpo->SetSearchName($searchname);
53
+            if (self::$decoder->getElementStartTag(SYNC_SEARCH_AND)) {
54
+                if (self::$decoder->getElementStartTag(SYNC_FOLDERID)) {
55
+                    $searchfolderid = self::$decoder->getElementContent();
56
+                    $cpo->SetSearchFolderid($searchfolderid);
57
+                    if (!self::$decoder->getElementEndTag()) { // SYNC_FOLDERTYPE
58
+                        return false;
59
+                    }
60
+                }
61
+
62
+                if (self::$decoder->getElementStartTag(SYNC_FOLDERTYPE)) {
63
+                    $searchclass = self::$decoder->getElementContent();
64
+                    $cpo->SetSearchClass($searchclass);
65
+                    if (!self::$decoder->getElementEndTag()) { // SYNC_FOLDERTYPE
66
+                        return false;
67
+                    }
68
+                }
69
+
70
+                if (self::$decoder->getElementStartTag(SYNC_FOLDERID)) {
71
+                    $searchfolderid = self::$decoder->getElementContent();
72
+                    $cpo->SetSearchFolderid($searchfolderid);
73
+                    if (!self::$decoder->getElementEndTag()) { // SYNC_FOLDERTYPE
74
+                        return false;
75
+                    }
76
+                }
77
+
78
+                if (self::$decoder->getElementStartTag(SYNC_SEARCH_FREETEXT)) {
79
+                    $searchfreetext = self::$decoder->getElementContent();
80
+                    $cpo->SetSearchFreeText($searchfreetext);
81
+                    if (!self::$decoder->getElementEndTag()) { // SYNC_SEARCH_FREETEXT
82
+                        return false;
83
+                    }
84
+                }
85
+
86
+                // TODO - review
87
+                if (self::$decoder->getElementStartTag(SYNC_SEARCH_GREATERTHAN)) {
88
+                    if (self::$decoder->getElementStartTag(SYNC_POOMMAIL_DATERECEIVED)) {
89
+                        $datereceivedgreater = true;
90
+                        if (($dam = self::$decoder->getElementContent()) !== false) {
91
+                            $datereceivedgreater = true;
92
+                            if (!self::$decoder->getElementEndTag()) {
93
+                                return false;
94
+                            }
95
+                        }
96
+                        $cpo->SetSearchDateReceivedGreater($datereceivedgreater);
97
+                    }
98
+
99
+                    if (self::$decoder->getElementStartTag(SYNC_SEARCH_VALUE)) {
100
+                        $searchvalue = self::$decoder->getElementContent();
101
+                        $cpo->SetSearchValueGreater($searchvalue);
102
+                        if (!self::$decoder->getElementEndTag()) { // SYNC_SEARCH_VALUE
103
+                            return false;
104
+                        }
105
+                    }
106
+
107
+                    if (!self::$decoder->getElementEndTag()) { // SYNC_SEARCH_GREATERTHAN
108
+                        return false;
109
+                    }
110
+                }
111
+
112
+                if (self::$decoder->getElementStartTag(SYNC_SEARCH_LESSTHAN)) {
113
+                    if (self::$decoder->getElementStartTag(SYNC_POOMMAIL_DATERECEIVED)) {
114
+                        $datereceivedless = true;
115
+                        if (($dam = self::$decoder->getElementContent()) !== false) {
116
+                            $datereceivedless = true;
117
+                            if (!self::$decoder->getElementEndTag()) {
118
+                                return false;
119
+                            }
120
+                        }
121
+                        $cpo->SetSearchDateReceivedLess($datereceivedless);
122
+                    }
123
+
124
+                    if (self::$decoder->getElementStartTag(SYNC_SEARCH_VALUE)) {
125
+                        $searchvalue = self::$decoder->getElementContent();
126
+                        $cpo->SetSearchValueLess($searchvalue);
127
+                        if (!self::$decoder->getElementEndTag()) { // SYNC_SEARCH_VALUE
128
+                            return false;
129
+                        }
130
+                    }
131
+
132
+                    if (!self::$decoder->getElementEndTag()) { // SYNC_SEARCH_LESSTHAN
133
+                        return false;
134
+                    }
135
+                }
136
+
137
+                if (self::$decoder->getElementStartTag(SYNC_SEARCH_FREETEXT)) {
138
+                    $searchfreetext = self::$decoder->getElementContent();
139
+                    $cpo->SetSearchFreeText($searchfreetext);
140
+                    if (!self::$decoder->getElementEndTag()) { // SYNC_SEARCH_FREETEXT
141
+                        return false;
142
+                    }
143
+                }
144
+
145
+                if (!self::$decoder->getElementEndTag()) { // SYNC_SEARCH_AND
146
+                    return false;
147
+                }
148
+            }
149
+            elseif (self::$decoder->getElementStartTag(SYNC_SEARCH_EQUALTO)) {
150
+                // linkid can be an empty tag as well as have value
151
+                if (self::$decoder->getElementStartTag(SYNC_DOCUMENTLIBRARY_LINKID)) {
152
+                    if (($linkId = self::$decoder->getElementContent()) !== false) {
153
+                        $cpo->SetLinkId($linkId);
154
+                        if (!self::$decoder->getElementEndTag()) { // SYNC_DOCUMENTLIBRARY_LINKID
155
+                            return false;
156
+                        }
157
+                    }
158
+                }
159
+
160
+                if (self::$decoder->getElementStartTag(SYNC_SEARCH_VALUE)) {
161
+                    $searchvalue = self::$decoder->getElementContent();
162
+                    $cpo->SetSearchValueEqualTo($searchvalue);
163
+                    if (!self::$decoder->getElementEndTag()) { // SYNC_SEARCH_VALUE
164
+                        return false;
165
+                    }
166
+                }
167
+
168
+                if (!self::$decoder->getElementEndTag()) { // SYNC_SEARCH_EQUALTO
169
+                    return false;
170
+                }
171
+            }
172
+
173
+            if (!self::$decoder->getElementEndTag()) { // SYNC_SEARCH_QUERY
174
+                return false;
175
+            }
176
+        }
177
+
178
+        if (self::$decoder->getElementStartTag(SYNC_SEARCH_OPTIONS)) {
179
+            WBXMLDecoder::ResetInWhile("searchOptions");
180
+            while (WBXMLDecoder::InWhile("searchOptions")) {
181
+                if (self::$decoder->getElementStartTag(SYNC_SEARCH_RANGE)) {
182
+                    $searchrange = self::$decoder->getElementContent();
183
+                    $cpo->SetSearchRange($searchrange);
184
+                    if (!self::$decoder->getElementEndTag()) {
185
+                        return false;
186
+                    }
187
+                }
188
+
189
+                if (self::$decoder->getElementStartTag(SYNC_SEARCH_REBUILDRESULTS)) {
190
+                    $rebuildresults = true;
191
+                    if (($dam = self::$decoder->getElementContent()) !== false) {
192
+                        $rebuildresults = true;
193
+                        if (!self::$decoder->getElementEndTag()) {
194
+                            return false;
195
+                        }
196
+                    }
197
+                    $cpo->SetSearchRebuildResults($rebuildresults);
198
+                }
199
+
200
+                if (self::$decoder->getElementStartTag(SYNC_SEARCH_DEEPTRAVERSAL)) {
201
+                    $deeptraversal = true;
202
+                    if (($dam = self::$decoder->getElementContent()) !== false) {
203
+                        $deeptraversal = true;
204
+                        if (!self::$decoder->getElementEndTag()) {
205
+                            return false;
206
+                        }
207
+                    }
208
+                    $cpo->SetSearchDeepTraversal($deeptraversal);
209
+                }
210
+
211
+                if (self::$decoder->getElementStartTag(SYNC_MIMESUPPORT)) {
212
+                    $cpo->SetMimeSupport(self::$decoder->getElementContent());
213
+                    if (!self::$decoder->getElementEndTag()) {
214
+                        return false;
215
+                    }
216
+                }
217
+
218
+                // TODO body preferences
219
+                while (self::$decoder->getElementStartTag(SYNC_AIRSYNCBASE_BODYPREFERENCE)) {
220
+                    if (self::$decoder->getElementStartTag(SYNC_AIRSYNCBASE_TYPE)) {
221
+                        $bptype = self::$decoder->getElementContent();
222
+                        $cpo->BodyPreference($bptype);
223
+                        if (!self::$decoder->getElementEndTag()) {
224
+                            return false;
225
+                        }
226
+                    }
227
+
228
+                    if (self::$decoder->getElementStartTag(SYNC_AIRSYNCBASE_TRUNCATIONSIZE)) {
229
+                        $cpo->BodyPreference($bptype)->SetTruncationSize(self::$decoder->getElementContent());
230
+                        if (!self::$decoder->getElementEndTag()) {
231
+                            return false;
232
+                        }
233
+                    }
234
+
235
+                    if (self::$decoder->getElementStartTag(SYNC_AIRSYNCBASE_ALLORNONE)) {
236
+                        $cpo->BodyPreference($bptype)->SetAllOrNone(self::$decoder->getElementContent());
237
+                        if (!self::$decoder->getElementEndTag()) {
238
+                            return false;
239
+                        }
240
+                    }
241
+
242
+                    if (self::$decoder->getElementStartTag(SYNC_AIRSYNCBASE_PREVIEW)) {
243
+                        $cpo->BodyPreference($bptype)->SetPreview(self::$decoder->getElementContent());
244
+                        if (!self::$decoder->getElementEndTag()) {
245
+                            return false;
246
+                        }
247
+                    }
248
+
249
+                    if (!self::$decoder->getElementEndTag()) {
250
+                        return false;
251
+                    }
252
+                }
253
+
254
+                if (self::$decoder->getElementStartTag(SYNC_AIRSYNCBASE_BODYPARTPREFERENCE)) {
255
+                    if (self::$decoder->getElementStartTag(SYNC_AIRSYNCBASE_TYPE)) {
256
+                        $bpptype = self::$decoder->getElementContent();
257
+                        $cpo->BodyPartPreference($bpptype);
258
+                        if (!self::$decoder->getElementEndTag()) {
259
+                            return false;
260
+                        }
261
+                    }
262
+
263
+                    if (self::$decoder->getElementStartTag(SYNC_AIRSYNCBASE_TRUNCATIONSIZE)) {
264
+                        $cpo->BodyPartPreference($bpptype)->SetTruncationSize(self::$decoder->getElementContent());
265
+                        if (!self::$decoder->getElementEndTag()) {
266
+                            return false;
267
+                        }
268
+                    }
269
+
270
+                    if (self::$decoder->getElementStartTag(SYNC_AIRSYNCBASE_ALLORNONE)) {
271
+                        $cpo->BodyPartPreference($bpptype)->SetAllOrNone(self::$decoder->getElementContent());
272
+                        if (!self::$decoder->getElementEndTag()) {
273
+                            return false;
274
+                        }
275
+                    }
276
+
277
+                    if (self::$decoder->getElementStartTag(SYNC_AIRSYNCBASE_PREVIEW)) {
278
+                        $cpo->BodyPartPreference($bpptype)->SetPreview(self::$decoder->getElementContent());
279
+                        if (!self::$decoder->getElementEndTag()) {
280
+                            return false;
281
+                        }
282
+                    }
283
+
284
+                    if (!self::$decoder->getElementEndTag()) {
285
+                        return false;
286
+                    }
287
+                }
288
+
289
+                if (self::$decoder->getElementStartTag(SYNC_RIGHTSMANAGEMENT_SUPPORT)) {
290
+                    $cpo->SetRmSupport(self::$decoder->getElementContent());
291
+                    if (!self::$decoder->getElementEndTag()) {
292
+                        return false;
293
+                    }
294
+                }
295
+
296
+                if (self::$decoder->getElementStartTag(SYNC_SEARCH_PICTURE)) { // TODO - do something with maxsize and maxpictures in the backend
297
+                    $searchpicture = new SyncResolveRecipientsPicture();
298
+                    if (self::$decoder->getElementStartTag(SYNC_SEARCH_MAXSIZE)) {
299
+                        $searchpicture->maxsize = self::$decoder->getElementContent();
300
+                        if (!self::$decoder->getElementEndTag()) {
301
+                            return false;
302
+                        }
303
+                    }
304
+
305
+                    if (self::$decoder->getElementStartTag(SYNC_SEARCH_MAXPICTURES)) {
306
+                        $searchpicture->maxpictures = self::$decoder->getElementContent();
307
+                        if (!self::$decoder->getElementEndTag()) {
308
+                            return false;
309
+                        }
310
+                    }
311
+
312
+                    // iOs devices send empty picture tag: <Search:Picture/>
313
+                    if (($sp = self::$decoder->getElementContent()) !== false) {
314
+                        if (!self::$decoder->getElementEndTag()) {
315
+                            return false;
316
+                        }
317
+                    }
318
+                }
319
+
320
+                $e = self::$decoder->peek();
321
+                if ($e[EN_TYPE] == EN_TYPE_ENDTAG) {
322
+                    self::$decoder->getElementEndTag();
323
+
324
+                    break;
325
+                }
326
+            }
327
+        }
328
+        if (!self::$decoder->getElementEndTag()) { // store
329
+            return false;
330
+        }
331
+
332
+        if (!self::$decoder->getElementEndTag()) { // search
333
+            return false;
334
+        }
335
+
336
+        // get SearchProvider
337
+        $searchprovider = GSync::GetBackend()->GetSearchProvider();
338
+        $status = SYNC_SEARCHSTATUS_SUCCESS;
339
+        $rows = [];
340
+
341
+        // TODO support other searches
342
+        if ($searchprovider->SupportsType($searchname)) {
343
+            $storestatus = SYNC_SEARCHSTATUS_STORE_SUCCESS;
344
+
345
+            try {
346
+                if ($searchname == ISearchProvider::SEARCH_GAL) {
347
+                    // get search results from the searchprovider
348
+                    $rows = $searchprovider->GetGALSearchResults($searchquery, $searchrange, $searchpicture);
349
+                }
350
+                elseif ($searchname == ISearchProvider::SEARCH_MAILBOX) {
351
+                    $backendFolderId = self::$deviceManager->GetBackendIdForFolderId($cpo->GetSearchFolderid());
352
+                    $cpo->SetSearchFolderid($backendFolderId);
353
+                    $rows = $searchprovider->GetMailboxSearchResults($cpo);
354
+                }
355
+            }
356
+            catch (StatusException $stex) {
357
+                $storestatus = $stex->getCode();
358
+            }
359
+        }
360
+        else {
361
+            $rows = ['searchtotal' => 0];
362
+            $status = SYNC_SEARCHSTATUS_SERVERERROR;
363
+            SLog::Write(LOGLEVEL_WARN, sprintf("Searchtype '%s' is not supported.", $searchname));
364
+            self::$topCollector->AnnounceInformation(sprintf("Unsupported type '%s''", $searchname), true);
365
+        }
366
+        $searchprovider->Disconnect();
367
+
368
+        self::$topCollector->AnnounceInformation(sprintf("'%s' search found %d results", $searchname, (isset($rows['searchtotal']) ? $rows['searchtotal'] : 0)), true);
369
+
370
+        self::$encoder->startWBXML();
371
+        self::$encoder->startTag(SYNC_SEARCH_SEARCH);
372
+
373
+        self::$encoder->startTag(SYNC_SEARCH_STATUS);
374
+        self::$encoder->content($status);
375
+        self::$encoder->endTag();
376
+
377
+        if ($status == SYNC_SEARCHSTATUS_SUCCESS) {
378
+            self::$encoder->startTag(SYNC_SEARCH_RESPONSE);
379
+            self::$encoder->startTag(SYNC_SEARCH_STORE);
380
+
381
+            self::$encoder->startTag(SYNC_SEARCH_STATUS);
382
+            self::$encoder->content($storestatus);
383
+            self::$encoder->endTag();
384
+
385
+            if (isset($rows['range'])) {
386
+                $searchrange = $rows['range'];
387
+                unset($rows['range']);
388
+            }
389
+            if (isset($rows['searchtotal'])) {
390
+                $searchtotal = $rows['searchtotal'];
391
+                unset($rows['searchtotal']);
392
+            }
393
+            if ($searchname == ISearchProvider::SEARCH_GAL) {
394
+                if (is_array($rows) && !empty($rows)) {
395
+                    foreach ($rows as $u) {
396
+                        self::$encoder->startTag(SYNC_SEARCH_RESULT);
397
+                        self::$encoder->startTag(SYNC_SEARCH_PROPERTIES);
398
+
399
+                        self::$encoder->startTag(SYNC_GAL_DISPLAYNAME);
400
+                        self::$encoder->content((isset($u[SYNC_GAL_DISPLAYNAME])) ? $u[SYNC_GAL_DISPLAYNAME] : "No name");
401
+                        self::$encoder->endTag();
402
+
403
+                        if (isset($u[SYNC_GAL_PHONE])) {
404
+                            self::$encoder->startTag(SYNC_GAL_PHONE);
405
+                            self::$encoder->content($u[SYNC_GAL_PHONE]);
406
+                            self::$encoder->endTag();
407
+                        }
408
+
409
+                        if (isset($u[SYNC_GAL_OFFICE])) {
410
+                            self::$encoder->startTag(SYNC_GAL_OFFICE);
411
+                            self::$encoder->content($u[SYNC_GAL_OFFICE]);
412
+                            self::$encoder->endTag();
413
+                        }
414
+
415
+                        if (isset($u[SYNC_GAL_TITLE])) {
416
+                            self::$encoder->startTag(SYNC_GAL_TITLE);
417
+                            self::$encoder->content($u[SYNC_GAL_TITLE]);
418
+                            self::$encoder->endTag();
419
+                        }
420
+
421
+                        if (isset($u[SYNC_GAL_COMPANY])) {
422
+                            self::$encoder->startTag(SYNC_GAL_COMPANY);
423
+                            self::$encoder->content($u[SYNC_GAL_COMPANY]);
424
+                            self::$encoder->endTag();
425
+                        }
426
+
427
+                        if (isset($u[SYNC_GAL_ALIAS])) {
428
+                            self::$encoder->startTag(SYNC_GAL_ALIAS);
429
+                            self::$encoder->content($u[SYNC_GAL_ALIAS]);
430
+                            self::$encoder->endTag();
431
+                        }
432
+
433
+                        // Always send the firstname, even empty. Nokia needs this to display the entry
434
+                        self::$encoder->startTag(SYNC_GAL_FIRSTNAME);
435
+                        self::$encoder->content((isset($u[SYNC_GAL_FIRSTNAME])) ? $u[SYNC_GAL_FIRSTNAME] : "");
436
+                        self::$encoder->endTag();
437
+
438
+                        self::$encoder->startTag(SYNC_GAL_LASTNAME);
439
+                        self::$encoder->content((isset($u[SYNC_GAL_LASTNAME])) ? $u[SYNC_GAL_LASTNAME] : "No name");
440
+                        self::$encoder->endTag();
441
+
442
+                        if (isset($u[SYNC_GAL_HOMEPHONE])) {
443
+                            self::$encoder->startTag(SYNC_GAL_HOMEPHONE);
444
+                            self::$encoder->content($u[SYNC_GAL_HOMEPHONE]);
445
+                            self::$encoder->endTag();
446
+                        }
447
+
448
+                        if (isset($u[SYNC_GAL_MOBILEPHONE])) {
449
+                            self::$encoder->startTag(SYNC_GAL_MOBILEPHONE);
450
+                            self::$encoder->content($u[SYNC_GAL_MOBILEPHONE]);
451
+                            self::$encoder->endTag();
452
+                        }
453
+
454
+                        self::$encoder->startTag(SYNC_GAL_EMAILADDRESS);
455
+                        self::$encoder->content((isset($u[SYNC_GAL_EMAILADDRESS])) ? $u[SYNC_GAL_EMAILADDRESS] : "");
456
+                        self::$encoder->endTag();
457
+
458
+                        if (isset($u[SYNC_GAL_PICTURE])) {
459
+                            self::$encoder->startTag(SYNC_GAL_PICTURE);
460
+                            self::$encoder->startTag(SYNC_GAL_STATUS);
461
+                            self::$encoder->content(SYNC_SEARCHSTATUS_PICTURE_SUCCESS); // FIXME: status code
462
+                                                self::$encoder->endTag(); // SYNC_SEARCH_STATUS
463
+
464
+                                                self::$encoder->startTag(SYNC_GAL_DATA);
465
+                            self::$encoder->contentStream($u[SYNC_GAL_PICTURE], false, true);
466
+                            self::$encoder->endTag(); // SYNC_GAL_DATA
467
+                                            self::$encoder->endTag(); // SYNC_GAL_PICTURE
468
+                        }
469
+
470
+                        self::$encoder->endTag(); // result
471
+                                self::$encoder->endTag(); // properties
472
+                    }
473
+                }
474
+            }
475
+            elseif ($searchname == ISearchProvider::SEARCH_MAILBOX) {
476
+                foreach ($rows as $u) {
477
+                    // TODO: unclear if any clients *require* the folder id where the message is located (it's not available anymore)
478
+                    // $folderid = self::$deviceManager->GetFolderIdForBackendId($u['folderid']);
479
+
480
+                    self::$encoder->startTag(SYNC_SEARCH_RESULT);
481
+                    self::$encoder->startTag(SYNC_FOLDERTYPE);
482
+                    self::$encoder->content($u['class']);
483
+                    self::$encoder->endTag();
484
+                    self::$encoder->startTag(SYNC_SEARCH_LONGID);
485
+                    self::$encoder->content($u['longid']);
486
+                    self::$encoder->endTag();
487
+                    // self::$encoder->startTag(SYNC_FOLDERID);
488
+                    // self::$encoder->content($folderid);
489
+                    // self::$encoder->endTag();
490
+
491
+                    self::$encoder->startTag(SYNC_SEARCH_PROPERTIES);
492
+                    $message = self::$backend->Fetch(false, $u['longid'], $cpo);
493
+                    $message->Encode(self::$encoder);
494
+
495
+                    self::$encoder->endTag(); // result
496
+                            self::$encoder->endTag(); // properties
497
+                }
498
+            }
499
+            // it seems that android 4 requires range and searchtotal
500
+            // or it won't display the search results
501
+            if (isset($searchrange)) {
502
+                self::$encoder->startTag(SYNC_SEARCH_RANGE);
503
+                self::$encoder->content($searchrange);
504
+                self::$encoder->endTag();
505
+            }
506
+            if (isset($searchtotal) && $searchtotal > 0) {
507
+                self::$encoder->startTag(SYNC_SEARCH_TOTAL);
508
+                self::$encoder->content($searchtotal);
509
+                self::$encoder->endTag();
510
+            }
511
+
512
+            self::$encoder->endTag(); // store
513
+                self::$encoder->endTag(); // response
514
+        }
515
+        self::$encoder->endTag(); // search
516
+
517
+        return true;
518
+    }
519 519
 }
Please login to merge, or discard this patch.
Braces   +5 added lines, -10 removed lines patch added patch discarded remove patch
@@ -145,8 +145,7 @@  discard block
 block discarded – undo
145 145
 				if (!self::$decoder->getElementEndTag()) { // SYNC_SEARCH_AND
146 146
 					return false;
147 147
 				}
148
-			}
149
-			elseif (self::$decoder->getElementStartTag(SYNC_SEARCH_EQUALTO)) {
148
+			} elseif (self::$decoder->getElementStartTag(SYNC_SEARCH_EQUALTO)) {
150 149
 				// linkid can be an empty tag as well as have value
151 150
 				if (self::$decoder->getElementStartTag(SYNC_DOCUMENTLIBRARY_LINKID)) {
152 151
 					if (($linkId = self::$decoder->getElementContent()) !== false) {
@@ -346,18 +345,15 @@  discard block
 block discarded – undo
346 345
 				if ($searchname == ISearchProvider::SEARCH_GAL) {
347 346
 					// get search results from the searchprovider
348 347
 					$rows = $searchprovider->GetGALSearchResults($searchquery, $searchrange, $searchpicture);
349
-				}
350
-				elseif ($searchname == ISearchProvider::SEARCH_MAILBOX) {
348
+				} elseif ($searchname == ISearchProvider::SEARCH_MAILBOX) {
351 349
 					$backendFolderId = self::$deviceManager->GetBackendIdForFolderId($cpo->GetSearchFolderid());
352 350
 					$cpo->SetSearchFolderid($backendFolderId);
353 351
 					$rows = $searchprovider->GetMailboxSearchResults($cpo);
354 352
 				}
355
-			}
356
-			catch (StatusException $stex) {
353
+			} catch (StatusException $stex) {
357 354
 				$storestatus = $stex->getCode();
358 355
 			}
359
-		}
360
-		else {
356
+		} else {
361 357
 			$rows = ['searchtotal' => 0];
362 358
 			$status = SYNC_SEARCHSTATUS_SERVERERROR;
363 359
 			SLog::Write(LOGLEVEL_WARN, sprintf("Searchtype '%s' is not supported.", $searchname));
@@ -471,8 +467,7 @@  discard block
 block discarded – undo
471 467
 								self::$encoder->endTag(); // properties
472 468
 					}
473 469
 				}
474
-			}
475
-			elseif ($searchname == ISearchProvider::SEARCH_MAILBOX) {
470
+			} elseif ($searchname == ISearchProvider::SEARCH_MAILBOX) {
476 471
 				foreach ($rows as $u) {
477 472
 					// TODO: unclear if any clients *require* the folder id where the message is located (it's not available anymore)
478 473
 					// $folderid = self::$deviceManager->GetFolderIdForBackendId($u['folderid']);
Please login to merge, or discard this patch.
lib/request/requestprocessor.php 3 patches
Indentation   +134 added lines, -134 removed lines patch added patch discarded remove patch
@@ -11,138 +11,138 @@
 block discarded – undo
11 11
  */
12 12
 
13 13
 abstract class RequestProcessor {
14
-	protected static $backend;
15
-	protected static $deviceManager;
16
-	protected static $topCollector;
17
-	protected static $decoder;
18
-	protected static $encoder;
19
-	protected static $userIsAuthenticated;
20
-	protected static $specialHeaders;
21
-	protected static $waitTime = 0;
22
-
23
-	/**
24
-	 * Authenticates the remote user
25
-	 * The sent HTTP authentication information is used to on Backend->Logon().
26
-	 * As second step the GET-User verified by Backend->Setup() for permission check
27
-	 * Request::GetGETUser() is usually the same as the Request::GetAuthUser().
28
-	 * If the GETUser is different from the AuthUser, the AuthUser MUST HAVE admin
29
-	 * permissions on GETUsers data store. Only then the Setup() will be successful.
30
-	 * This allows the user 'john' to do operations as user 'joe' if he has sufficient privileges.
31
-	 *
32
-	 * @throws AuthenticationRequiredException
33
-	 *
34
-	 * @return
35
-	 */
36
-	public static function Authenticate() {
37
-		self::$userIsAuthenticated = false;
38
-
39
-		// when a certificate is sent, allow authentication only as the certificate owner
40
-		if (defined("CERTIFICATE_OWNER_PARAMETER") && isset($_SERVER[CERTIFICATE_OWNER_PARAMETER]) && strtolower($_SERVER[CERTIFICATE_OWNER_PARAMETER]) != strtolower(Request::GetAuthUser())) {
41
-			throw new AuthenticationRequiredException(sprintf("Access denied. Access is allowed only for the certificate owner '%s'", $_SERVER[CERTIFICATE_OWNER_PARAMETER]));
42
-		}
43
-
44
-		if (Request::GetImpersonatedUser() && strcasecmp(Request::GetAuthUser(), Request::GetImpersonatedUser()) !== 0) {
45
-			SLog::Write(LOGLEVEL_DEBUG, sprintf("RequestProcessor->Authenticate(): Impersonation active - authenticating: '%s' - impersonating '%s'", Request::GetAuthUser(), Request::GetImpersonatedUser()));
46
-		}
47
-
48
-		$backend = GSync::GetBackend();
49
-		if ($backend->Logon(Request::GetAuthUser(), Request::GetAuthDomain(), Request::GetAuthPassword()) == false) {
50
-			throw new AuthenticationRequiredException("Access denied. Username or password incorrect");
51
-		}
52
-
53
-		// mark this request as "authenticated"
54
-		self::$userIsAuthenticated = true;
55
-	}
56
-
57
-	/**
58
-	 * Indicates if the user was "authenticated".
59
-	 *
60
-	 * @return bool
61
-	 */
62
-	public static function isUserAuthenticated() {
63
-		if (!isset(self::$userIsAuthenticated)) {
64
-			return false;
65
-		}
66
-
67
-		return self::$userIsAuthenticated;
68
-	}
69
-
70
-	/**
71
-	 * Initialize the RequestProcessor.
72
-	 *
73
-	 * @return
74
-	 */
75
-	public static function Initialize() {
76
-		self::$backend = GSync::GetBackend();
77
-		self::$deviceManager = GSync::GetDeviceManager(false);
78
-		self::$topCollector = GSync::GetTopCollector();
79
-
80
-		if (!GSync::CommandNeedsPlainInput(Request::GetCommandCode())) {
81
-			self::$decoder = new WBXMLDecoder(Request::GetInputStream());
82
-		}
83
-
84
-		self::$encoder = new WBXMLEncoder(Request::GetOutputStream(), Request::GetGETAcceptMultipart());
85
-		self::$waitTime = 0;
86
-	}
87
-
88
-	/**
89
-	 * Loads the command handler and processes a command sent from the mobile.
90
-	 *
91
-	 * @return bool
92
-	 */
93
-	public static function HandleRequest() {
94
-		$handler = GSync::GetRequestHandlerForCommand(Request::GetCommandCode());
95
-
96
-		// if there is an error decoding wbxml, consume remaining data and include it in the WBXMLException
97
-		try {
98
-			if (!$handler->Handle(Request::GetCommandCode())) {
99
-				throw new WBXMLException(sprintf("Unknown error in %s->Handle()", get_class($handler)));
100
-			}
101
-		}
102
-		catch (Exception $ex) {
103
-			// Log 10 KB of the WBXML data
104
-			SLog::Write(LOGLEVEL_FATAL, "WBXML 10K debug data: " . Request::GetInputAsBase64(10240), false);
105
-
106
-			throw $ex;
107
-		}
108
-
109
-		// also log WBXML in happy case
110
-		if (SLog::IsWbxmlDebugEnabled()) {
111
-			// Log 4 KB in the happy case
112
-			SLog::Write(LOGLEVEL_WBXML, "WBXML-IN : " . Request::GetInputAsBase64(4096), false);
113
-		}
114
-
115
-		return true;
116
-	}
117
-
118
-	/**
119
-	 * Returns any additional headers which should be sent to the mobile.
120
-	 *
121
-	 * @return array
122
-	 */
123
-	public static function GetSpecialHeaders() {
124
-		if (!isset(self::$specialHeaders) || !is_array(self::$specialHeaders)) {
125
-			return [];
126
-		}
127
-
128
-		return self::$specialHeaders;
129
-	}
130
-
131
-	/**
132
-	 * Returns the amount of seconds RequestProcessor waited e.g. during Ping.
133
-	 *
134
-	 * @return int
135
-	 */
136
-	public static function GetWaitTime() {
137
-		return self::$waitTime;
138
-	}
139
-
140
-	/**
141
-	 * Handles a command.
142
-	 *
143
-	 * @param int $commandCode
144
-	 *
145
-	 * @return bool
146
-	 */
147
-	abstract public function Handle($commandCode);
14
+    protected static $backend;
15
+    protected static $deviceManager;
16
+    protected static $topCollector;
17
+    protected static $decoder;
18
+    protected static $encoder;
19
+    protected static $userIsAuthenticated;
20
+    protected static $specialHeaders;
21
+    protected static $waitTime = 0;
22
+
23
+    /**
24
+     * Authenticates the remote user
25
+     * The sent HTTP authentication information is used to on Backend->Logon().
26
+     * As second step the GET-User verified by Backend->Setup() for permission check
27
+     * Request::GetGETUser() is usually the same as the Request::GetAuthUser().
28
+     * If the GETUser is different from the AuthUser, the AuthUser MUST HAVE admin
29
+     * permissions on GETUsers data store. Only then the Setup() will be successful.
30
+     * This allows the user 'john' to do operations as user 'joe' if he has sufficient privileges.
31
+     *
32
+     * @throws AuthenticationRequiredException
33
+     *
34
+     * @return
35
+     */
36
+    public static function Authenticate() {
37
+        self::$userIsAuthenticated = false;
38
+
39
+        // when a certificate is sent, allow authentication only as the certificate owner
40
+        if (defined("CERTIFICATE_OWNER_PARAMETER") && isset($_SERVER[CERTIFICATE_OWNER_PARAMETER]) && strtolower($_SERVER[CERTIFICATE_OWNER_PARAMETER]) != strtolower(Request::GetAuthUser())) {
41
+            throw new AuthenticationRequiredException(sprintf("Access denied. Access is allowed only for the certificate owner '%s'", $_SERVER[CERTIFICATE_OWNER_PARAMETER]));
42
+        }
43
+
44
+        if (Request::GetImpersonatedUser() && strcasecmp(Request::GetAuthUser(), Request::GetImpersonatedUser()) !== 0) {
45
+            SLog::Write(LOGLEVEL_DEBUG, sprintf("RequestProcessor->Authenticate(): Impersonation active - authenticating: '%s' - impersonating '%s'", Request::GetAuthUser(), Request::GetImpersonatedUser()));
46
+        }
47
+
48
+        $backend = GSync::GetBackend();
49
+        if ($backend->Logon(Request::GetAuthUser(), Request::GetAuthDomain(), Request::GetAuthPassword()) == false) {
50
+            throw new AuthenticationRequiredException("Access denied. Username or password incorrect");
51
+        }
52
+
53
+        // mark this request as "authenticated"
54
+        self::$userIsAuthenticated = true;
55
+    }
56
+
57
+    /**
58
+     * Indicates if the user was "authenticated".
59
+     *
60
+     * @return bool
61
+     */
62
+    public static function isUserAuthenticated() {
63
+        if (!isset(self::$userIsAuthenticated)) {
64
+            return false;
65
+        }
66
+
67
+        return self::$userIsAuthenticated;
68
+    }
69
+
70
+    /**
71
+     * Initialize the RequestProcessor.
72
+     *
73
+     * @return
74
+     */
75
+    public static function Initialize() {
76
+        self::$backend = GSync::GetBackend();
77
+        self::$deviceManager = GSync::GetDeviceManager(false);
78
+        self::$topCollector = GSync::GetTopCollector();
79
+
80
+        if (!GSync::CommandNeedsPlainInput(Request::GetCommandCode())) {
81
+            self::$decoder = new WBXMLDecoder(Request::GetInputStream());
82
+        }
83
+
84
+        self::$encoder = new WBXMLEncoder(Request::GetOutputStream(), Request::GetGETAcceptMultipart());
85
+        self::$waitTime = 0;
86
+    }
87
+
88
+    /**
89
+     * Loads the command handler and processes a command sent from the mobile.
90
+     *
91
+     * @return bool
92
+     */
93
+    public static function HandleRequest() {
94
+        $handler = GSync::GetRequestHandlerForCommand(Request::GetCommandCode());
95
+
96
+        // if there is an error decoding wbxml, consume remaining data and include it in the WBXMLException
97
+        try {
98
+            if (!$handler->Handle(Request::GetCommandCode())) {
99
+                throw new WBXMLException(sprintf("Unknown error in %s->Handle()", get_class($handler)));
100
+            }
101
+        }
102
+        catch (Exception $ex) {
103
+            // Log 10 KB of the WBXML data
104
+            SLog::Write(LOGLEVEL_FATAL, "WBXML 10K debug data: " . Request::GetInputAsBase64(10240), false);
105
+
106
+            throw $ex;
107
+        }
108
+
109
+        // also log WBXML in happy case
110
+        if (SLog::IsWbxmlDebugEnabled()) {
111
+            // Log 4 KB in the happy case
112
+            SLog::Write(LOGLEVEL_WBXML, "WBXML-IN : " . Request::GetInputAsBase64(4096), false);
113
+        }
114
+
115
+        return true;
116
+    }
117
+
118
+    /**
119
+     * Returns any additional headers which should be sent to the mobile.
120
+     *
121
+     * @return array
122
+     */
123
+    public static function GetSpecialHeaders() {
124
+        if (!isset(self::$specialHeaders) || !is_array(self::$specialHeaders)) {
125
+            return [];
126
+        }
127
+
128
+        return self::$specialHeaders;
129
+    }
130
+
131
+    /**
132
+     * Returns the amount of seconds RequestProcessor waited e.g. during Ping.
133
+     *
134
+     * @return int
135
+     */
136
+    public static function GetWaitTime() {
137
+        return self::$waitTime;
138
+    }
139
+
140
+    /**
141
+     * Handles a command.
142
+     *
143
+     * @param int $commandCode
144
+     *
145
+     * @return bool
146
+     */
147
+    abstract public function Handle($commandCode);
148 148
 }
Please login to merge, or discard this patch.
Spacing   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -101,7 +101,7 @@  discard block
 block discarded – undo
101 101
 		}
102 102
 		catch (Exception $ex) {
103 103
 			// Log 10 KB of the WBXML data
104
-			SLog::Write(LOGLEVEL_FATAL, "WBXML 10K debug data: " . Request::GetInputAsBase64(10240), false);
104
+			SLog::Write(LOGLEVEL_FATAL, "WBXML 10K debug data: ".Request::GetInputAsBase64(10240), false);
105 105
 
106 106
 			throw $ex;
107 107
 		}
@@ -109,7 +109,7 @@  discard block
 block discarded – undo
109 109
 		// also log WBXML in happy case
110 110
 		if (SLog::IsWbxmlDebugEnabled()) {
111 111
 			// Log 4 KB in the happy case
112
-			SLog::Write(LOGLEVEL_WBXML, "WBXML-IN : " . Request::GetInputAsBase64(4096), false);
112
+			SLog::Write(LOGLEVEL_WBXML, "WBXML-IN : ".Request::GetInputAsBase64(4096), false);
113 113
 		}
114 114
 
115 115
 		return true;
Please login to merge, or discard this patch.
Braces   +1 added lines, -2 removed lines patch added patch discarded remove patch
@@ -98,8 +98,7 @@
 block discarded – undo
98 98
 			if (!$handler->Handle(Request::GetCommandCode())) {
99 99
 				throw new WBXMLException(sprintf("Unknown error in %s->Handle()", get_class($handler)));
100 100
 			}
101
-		}
102
-		catch (Exception $ex) {
101
+		} catch (Exception $ex) {
103 102
 			// Log 10 KB of the WBXML data
104 103
 			SLog::Write(LOGLEVEL_FATAL, "WBXML 10K debug data: " . Request::GetInputAsBase64(10240), false);
105 104
 
Please login to merge, or discard this patch.