Passed
Push — master ( 34e8da...f497d2 )
by
unknown
06:10 queued 02:50
created
mapi/mapi.util.php 3 patches
Indentation   +183 added lines, -183 removed lines patch added patch discarded remove patch
@@ -23,7 +23,7 @@  discard block
 block discarded – undo
23 23
  * @param mixed $guid
24 24
  */
25 25
 function makeGuid($guid) {
26
-	return pack("vvvv", hexdec(substr($guid, 5, 4)), hexdec(substr($guid, 1, 4)), hexdec(substr($guid, 10, 4)), hexdec(substr($guid, 15, 4))) . hex2bin(substr($guid, 20, 4)) . hex2bin(substr($guid, 25, 12));
26
+    return pack("vvvv", hexdec(substr($guid, 5, 4)), hexdec(substr($guid, 1, 4)), hexdec(substr($guid, 10, 4)), hexdec(substr($guid, 15, 4))) . hex2bin(substr($guid, 20, 4)) . hex2bin(substr($guid, 25, 12));
27 27
 }
28 28
 
29 29
 /**
@@ -34,37 +34,37 @@  discard block
 block discarded – undo
34 34
  *@return string The defined name for the MAPI error code
35 35
  */
36 36
 function get_mapi_error_name($errcode = null) {
37
-	if ($errcode === null) {
38
-		$errcode = mapi_last_hresult();
39
-	}
40
-
41
-	if ($errcode !== 0) {
42
-		// Retrieve constants categories, MAPI error names are defined
43
-		// in the 'user' category, since the WebApp code defines it in mapicode.php.
44
-		foreach (get_defined_constants(true)['user'] as $key => $value) {
45
-			/*
37
+    if ($errcode === null) {
38
+        $errcode = mapi_last_hresult();
39
+    }
40
+
41
+    if ($errcode !== 0) {
42
+        // Retrieve constants categories, MAPI error names are defined
43
+        // in the 'user' category, since the WebApp code defines it in mapicode.php.
44
+        foreach (get_defined_constants(true)['user'] as $key => $value) {
45
+            /*
46 46
 			 * If PHP encounters a number beyond the bounds of the integer type,
47 47
 			 * it will be interpreted as a float instead, so when comparing these error codes
48 48
 			 * we have to manually typecast value to integer, so float will be converted in integer,
49 49
 			 * but still its out of bound for integer limit so it will be auto adjusted to minus value
50 50
 			 */
51
-			if ($errcode == (int) $value) {
52
-				// Check that we have an actual MAPI error or warning definition
53
-				$prefix = substr($key, 0, 7);
54
-				if ($prefix == "MAPI_E_" || $prefix == "MAPI_W_") {
55
-					return $key;
56
-				}
57
-			}
58
-		}
59
-	}
60
-	else {
61
-		return "NOERROR";
62
-	}
63
-
64
-	// error code not found, return hex value (this is a fix for 64-bit systems, we can't use the dechex() function for this)
65
-	$result = unpack("H*", pack("N", $errcode));
66
-
67
-	return "0x" . $result[1];
51
+            if ($errcode == (int) $value) {
52
+                // Check that we have an actual MAPI error or warning definition
53
+                $prefix = substr($key, 0, 7);
54
+                if ($prefix == "MAPI_E_" || $prefix == "MAPI_W_") {
55
+                    return $key;
56
+                }
57
+            }
58
+        }
59
+    }
60
+    else {
61
+        return "NOERROR";
62
+    }
63
+
64
+    // error code not found, return hex value (this is a fix for 64-bit systems, we can't use the dechex() function for this)
65
+    $result = unpack("H*", pack("N", $errcode));
66
+
67
+    return "0x" . $result[1];
68 68
 }
69 69
 
70 70
 /**
@@ -78,66 +78,66 @@  discard block
 block discarded – undo
78 78
  * @param mixed $mapping
79 79
  */
80 80
 function getPropIdsFromStrings($store, $mapping) {
81
-	$props = [];
82
-
83
-	$ids = ["name" => [], "id" => [], "guid" => [], "type" => []]; // this array stores all the information needed to retrieve a named property
84
-	$num = 0;
85
-
86
-	// caching
87
-	$guids = [];
88
-
89
-	foreach ($mapping as $name => $val) {
90
-		if (is_string($val)) {
91
-			$split = explode(":", $val);
92
-
93
-			if (count($split) != 3) { // invalid string, ignore
94
-				trigger_error(sprintf("Invalid property: %s \"%s\"", $name, $val), E_USER_NOTICE);
95
-
96
-				continue;
97
-			}
98
-
99
-			if (substr($split[2], 0, 2) == "0x") {
100
-				$id = hexdec(substr($split[2], 2));
101
-			}
102
-			else {
103
-				$id = $split[2];
104
-			}
105
-
106
-			// have we used this guid before?
107
-			if (!defined($split[1])) {
108
-				if (!array_key_exists($split[1], $guids)) {
109
-					$guids[$split[1]] = makeguid($split[1]);
110
-				}
111
-				$guid = $guids[$split[1]];
112
-			}
113
-			else {
114
-				$guid = constant($split[1]);
115
-			}
116
-
117
-			// temp store info about named prop, so we have to call mapi_getidsfromnames just one time
118
-			$ids["name"][$num] = $name;
119
-			$ids["id"][$num] = $id;
120
-			$ids["guid"][$num] = $guid;
121
-			$ids["type"][$num] = $split[0];
122
-			++$num;
123
-		}
124
-		else {
125
-			// not a named property
126
-			$props[$name] = $val;
127
-		}
128
-	}
129
-
130
-	if (empty($ids["id"])) {
131
-		return $props;
132
-	}
133
-
134
-	// get the ids
135
-	$named = mapi_getidsfromnames($store, $ids["id"], $ids["guid"]);
136
-	foreach ($named as $num => $prop) {
137
-		$props[$ids["name"][$num]] = mapi_prop_tag(constant($ids["type"][$num]), mapi_prop_id($prop));
138
-	}
139
-
140
-	return $props;
81
+    $props = [];
82
+
83
+    $ids = ["name" => [], "id" => [], "guid" => [], "type" => []]; // this array stores all the information needed to retrieve a named property
84
+    $num = 0;
85
+
86
+    // caching
87
+    $guids = [];
88
+
89
+    foreach ($mapping as $name => $val) {
90
+        if (is_string($val)) {
91
+            $split = explode(":", $val);
92
+
93
+            if (count($split) != 3) { // invalid string, ignore
94
+                trigger_error(sprintf("Invalid property: %s \"%s\"", $name, $val), E_USER_NOTICE);
95
+
96
+                continue;
97
+            }
98
+
99
+            if (substr($split[2], 0, 2) == "0x") {
100
+                $id = hexdec(substr($split[2], 2));
101
+            }
102
+            else {
103
+                $id = $split[2];
104
+            }
105
+
106
+            // have we used this guid before?
107
+            if (!defined($split[1])) {
108
+                if (!array_key_exists($split[1], $guids)) {
109
+                    $guids[$split[1]] = makeguid($split[1]);
110
+                }
111
+                $guid = $guids[$split[1]];
112
+            }
113
+            else {
114
+                $guid = constant($split[1]);
115
+            }
116
+
117
+            // temp store info about named prop, so we have to call mapi_getidsfromnames just one time
118
+            $ids["name"][$num] = $name;
119
+            $ids["id"][$num] = $id;
120
+            $ids["guid"][$num] = $guid;
121
+            $ids["type"][$num] = $split[0];
122
+            ++$num;
123
+        }
124
+        else {
125
+            // not a named property
126
+            $props[$name] = $val;
127
+        }
128
+    }
129
+
130
+    if (empty($ids["id"])) {
131
+        return $props;
132
+    }
133
+
134
+    // get the ids
135
+    $named = mapi_getidsfromnames($store, $ids["id"], $ids["guid"]);
136
+    foreach ($named as $num => $prop) {
137
+        $props[$ids["name"][$num]] = mapi_prop_tag(constant($ids["type"][$num]), mapi_prop_id($prop));
138
+    }
139
+
140
+    return $props;
141 141
 }
142 142
 
143 143
 /**
@@ -153,11 +153,11 @@  discard block
 block discarded – undo
153 153
  * @return mixed Gives back false when there is no error, if there is, gives the error
154 154
  */
155 155
 function propIsError($property, $propArray) {
156
-	if (array_key_exists(mapi_prop_tag(PT_ERROR, mapi_prop_id($property)), $propArray)) {
157
-		return $propArray[mapi_prop_tag(PT_ERROR, mapi_prop_id($property))];
158
-	}
156
+    if (array_key_exists(mapi_prop_tag(PT_ERROR, mapi_prop_id($property)), $propArray)) {
157
+        return $propArray[mapi_prop_tag(PT_ERROR, mapi_prop_id($property))];
158
+    }
159 159
 
160
-	return false;
160
+    return false;
161 161
 }
162 162
 
163 163
 /* Macro Functions for PR_DISPLAY_TYPE_EX values */
@@ -167,7 +167,7 @@  discard block
 block discarded – undo
167 167
  * @param mixed $value
168 168
  */
169 169
 function DTE_IS_REMOTE_VALID($value) {
170
-	return (bool) ($value & DTE_FLAG_REMOTE_VALID);
170
+    return (bool) ($value & DTE_FLAG_REMOTE_VALID);
171 171
 }
172 172
 
173 173
 /**
@@ -176,15 +176,15 @@  discard block
 block discarded – undo
176 176
  * @param mixed $value
177 177
  */
178 178
 function DTE_IS_ACL_CAPABLE($value) {
179
-	return (bool) ($value & DTE_FLAG_ACL_CAPABLE);
179
+    return (bool) ($value & DTE_FLAG_ACL_CAPABLE);
180 180
 }
181 181
 
182 182
 function DTE_REMOTE($value) {
183
-	return ($value & DTE_MASK_REMOTE) >> 8;
183
+    return ($value & DTE_MASK_REMOTE) >> 8;
184 184
 }
185 185
 
186 186
 function DTE_LOCAL($value) {
187
-	return $value & DTE_MASK_LOCAL;
187
+    return $value & DTE_MASK_LOCAL;
188 188
 }
189 189
 
190 190
 /**
@@ -204,92 +204,92 @@  discard block
 block discarded – undo
204 204
  *                    expanded so that it seems that there are only many single appointments in the table.
205 205
  */
206 206
 function getCalendarItems($store, $calendar, $viewstart, $viewend, $propsrequested) {
207
-	$result = [];
208
-	$properties = getPropIdsFromStrings($store, [
209
-		"duedate" => "PT_SYSTIME:PSETID_Appointment:0x820e",
210
-		"startdate" => "PT_SYSTIME:PSETID_Appointment:0x820d",
211
-		"enddate_recurring" => "PT_SYSTIME:PSETID_Appointment:0x8236",
212
-		"recurring" => "PT_BOOLEAN:PSETID_Appointment:0x8223",
213
-		"recurring_data" => "PT_BINARY:PSETID_Appointment:0x8216",
214
-		"timezone_data" => "PT_BINARY:PSETID_Appointment:0x8233",
215
-		"label" => "PT_LONG:PSETID_Appointment:0x8214",
216
-	]);
217
-
218
-	// Create a restriction that will discard rows of appointments that are definitely not in our
219
-	// requested time frame
220
-
221
-	$table = mapi_folder_getcontentstable($calendar);
222
-
223
-	$restriction =
224
-		// OR
225
-		[
226
-			RES_OR,
227
-			[
228
-				[
229
-					RES_AND,    // Normal items: itemEnd must be after viewStart, itemStart must be before viewEnd
230
-					[
231
-						[
232
-							RES_PROPERTY,
233
-							[
234
-								RELOP => RELOP_GT,
235
-								ULPROPTAG => $properties["duedate"],
236
-								VALUE => $viewstart,
237
-							],
238
-						],
239
-						[
240
-							RES_PROPERTY,
241
-							[
242
-								RELOP => RELOP_LT,
243
-								ULPROPTAG => $properties["startdate"],
244
-								VALUE => $viewend,
245
-							],
246
-						],
247
-					],
248
-				],
249
-				// OR
250
-				[
251
-					RES_PROPERTY,
252
-					[
253
-						RELOP => RELOP_EQ,
254
-						ULPROPTAG => $properties["recurring"],
255
-						VALUE => true,
256
-					],
257
-				],
258
-			], // EXISTS OR
259
-		];        // global OR
260
-
261
-	// Get requested properties, plus whatever we need
262
-	$proplist = [PR_ENTRYID, $properties["recurring"], $properties["recurring_data"], $properties["timezone_data"]];
263
-	$proplist = array_merge($proplist, $propsrequested);
264
-
265
-	$rows = mapi_table_queryallrows($table, $proplist, $restriction);
266
-
267
-	// $rows now contains all the items that MAY be in the window; a recurring item needs expansion before including in the output.
268
-
269
-	foreach ($rows as $row) {
270
-		$items = [];
271
-
272
-		if (isset($row[$properties["recurring"]]) && $row[$properties["recurring"]]) {
273
-			// Recurring item
274
-			$rec = new Recurrence($store, $row);
275
-
276
-			// GetItems guarantees that the item overlaps the interval <$viewstart, $viewend>
277
-			$occurrences = $rec->getItems($viewstart, $viewend);
278
-			foreach ($occurrences as $occurrence) {
279
-				// The occurrence takes all properties from the main row, but overrides some properties (like start and end obviously)
280
-				$item = $occurrence + $row;
281
-				array_push($items, $item);
282
-			}
283
-		}
284
-		else {
285
-			// Normal item, it matched the search criteria and therefore overlaps the interval <$viewstart, $viewend>
286
-			array_push($items, $row);
287
-		}
288
-
289
-		$result = array_merge($result, $items);
290
-	}
291
-
292
-	// All items are guaranteed to overlap the interval <$viewstart, $viewend>. Note that we may be returning a few extra
293
-	// properties that the caller did not request (recurring, etc). This shouldn't be a problem though.
294
-	return $result;
207
+    $result = [];
208
+    $properties = getPropIdsFromStrings($store, [
209
+        "duedate" => "PT_SYSTIME:PSETID_Appointment:0x820e",
210
+        "startdate" => "PT_SYSTIME:PSETID_Appointment:0x820d",
211
+        "enddate_recurring" => "PT_SYSTIME:PSETID_Appointment:0x8236",
212
+        "recurring" => "PT_BOOLEAN:PSETID_Appointment:0x8223",
213
+        "recurring_data" => "PT_BINARY:PSETID_Appointment:0x8216",
214
+        "timezone_data" => "PT_BINARY:PSETID_Appointment:0x8233",
215
+        "label" => "PT_LONG:PSETID_Appointment:0x8214",
216
+    ]);
217
+
218
+    // Create a restriction that will discard rows of appointments that are definitely not in our
219
+    // requested time frame
220
+
221
+    $table = mapi_folder_getcontentstable($calendar);
222
+
223
+    $restriction =
224
+        // OR
225
+        [
226
+            RES_OR,
227
+            [
228
+                [
229
+                    RES_AND,    // Normal items: itemEnd must be after viewStart, itemStart must be before viewEnd
230
+                    [
231
+                        [
232
+                            RES_PROPERTY,
233
+                            [
234
+                                RELOP => RELOP_GT,
235
+                                ULPROPTAG => $properties["duedate"],
236
+                                VALUE => $viewstart,
237
+                            ],
238
+                        ],
239
+                        [
240
+                            RES_PROPERTY,
241
+                            [
242
+                                RELOP => RELOP_LT,
243
+                                ULPROPTAG => $properties["startdate"],
244
+                                VALUE => $viewend,
245
+                            ],
246
+                        ],
247
+                    ],
248
+                ],
249
+                // OR
250
+                [
251
+                    RES_PROPERTY,
252
+                    [
253
+                        RELOP => RELOP_EQ,
254
+                        ULPROPTAG => $properties["recurring"],
255
+                        VALUE => true,
256
+                    ],
257
+                ],
258
+            ], // EXISTS OR
259
+        ];        // global OR
260
+
261
+    // Get requested properties, plus whatever we need
262
+    $proplist = [PR_ENTRYID, $properties["recurring"], $properties["recurring_data"], $properties["timezone_data"]];
263
+    $proplist = array_merge($proplist, $propsrequested);
264
+
265
+    $rows = mapi_table_queryallrows($table, $proplist, $restriction);
266
+
267
+    // $rows now contains all the items that MAY be in the window; a recurring item needs expansion before including in the output.
268
+
269
+    foreach ($rows as $row) {
270
+        $items = [];
271
+
272
+        if (isset($row[$properties["recurring"]]) && $row[$properties["recurring"]]) {
273
+            // Recurring item
274
+            $rec = new Recurrence($store, $row);
275
+
276
+            // GetItems guarantees that the item overlaps the interval <$viewstart, $viewend>
277
+            $occurrences = $rec->getItems($viewstart, $viewend);
278
+            foreach ($occurrences as $occurrence) {
279
+                // The occurrence takes all properties from the main row, but overrides some properties (like start and end obviously)
280
+                $item = $occurrence + $row;
281
+                array_push($items, $item);
282
+            }
283
+        }
284
+        else {
285
+            // Normal item, it matched the search criteria and therefore overlaps the interval <$viewstart, $viewend>
286
+            array_push($items, $row);
287
+        }
288
+
289
+        $result = array_merge($result, $items);
290
+    }
291
+
292
+    // All items are guaranteed to overlap the interval <$viewstart, $viewend>. Note that we may be returning a few extra
293
+    // properties that the caller did not request (recurring, etc). This shouldn't be a problem though.
294
+    return $result;
295 295
 }
Please login to merge, or discard this patch.
Spacing   +7 added lines, -7 removed lines patch added patch discarded remove patch
@@ -23,7 +23,7 @@  discard block
 block discarded – undo
23 23
  * @param mixed $guid
24 24
  */
25 25
 function makeGuid($guid) {
26
-	return pack("vvvv", hexdec(substr($guid, 5, 4)), hexdec(substr($guid, 1, 4)), hexdec(substr($guid, 10, 4)), hexdec(substr($guid, 15, 4))) . hex2bin(substr($guid, 20, 4)) . hex2bin(substr($guid, 25, 12));
26
+	return pack("vvvv", hexdec(substr($guid, 5, 4)), hexdec(substr($guid, 1, 4)), hexdec(substr($guid, 10, 4)), hexdec(substr($guid, 15, 4))).hex2bin(substr($guid, 20, 4)).hex2bin(substr($guid, 25, 12));
27 27
 }
28 28
 
29 29
 /**
@@ -48,7 +48,7 @@  discard block
 block discarded – undo
48 48
 			 * we have to manually typecast value to integer, so float will be converted in integer,
49 49
 			 * but still its out of bound for integer limit so it will be auto adjusted to minus value
50 50
 			 */
51
-			if ($errcode == (int) $value) {
51
+			if ($errcode == (int)$value) {
52 52
 				// Check that we have an actual MAPI error or warning definition
53 53
 				$prefix = substr($key, 0, 7);
54 54
 				if ($prefix == "MAPI_E_" || $prefix == "MAPI_W_") {
@@ -64,7 +64,7 @@  discard block
 block discarded – undo
64 64
 	// error code not found, return hex value (this is a fix for 64-bit systems, we can't use the dechex() function for this)
65 65
 	$result = unpack("H*", pack("N", $errcode));
66 66
 
67
-	return "0x" . $result[1];
67
+	return "0x".$result[1];
68 68
 }
69 69
 
70 70
 /**
@@ -167,7 +167,7 @@  discard block
 block discarded – undo
167 167
  * @param mixed $value
168 168
  */
169 169
 function DTE_IS_REMOTE_VALID($value) {
170
-	return (bool) ($value & DTE_FLAG_REMOTE_VALID);
170
+	return (bool)($value & DTE_FLAG_REMOTE_VALID);
171 171
 }
172 172
 
173 173
 /**
@@ -176,7 +176,7 @@  discard block
 block discarded – undo
176 176
  * @param mixed $value
177 177
  */
178 178
 function DTE_IS_ACL_CAPABLE($value) {
179
-	return (bool) ($value & DTE_FLAG_ACL_CAPABLE);
179
+	return (bool)($value & DTE_FLAG_ACL_CAPABLE);
180 180
 }
181 181
 
182 182
 function DTE_REMOTE($value) {
@@ -226,7 +226,7 @@  discard block
 block discarded – undo
226 226
 			RES_OR,
227 227
 			[
228 228
 				[
229
-					RES_AND,    // Normal items: itemEnd must be after viewStart, itemStart must be before viewEnd
229
+					RES_AND, // Normal items: itemEnd must be after viewStart, itemStart must be before viewEnd
230 230
 					[
231 231
 						[
232 232
 							RES_PROPERTY,
@@ -256,7 +256,7 @@  discard block
 block discarded – undo
256 256
 					],
257 257
 				],
258 258
 			], // EXISTS OR
259
-		];        // global OR
259
+		]; // global OR
260 260
 
261 261
 	// Get requested properties, plus whatever we need
262 262
 	$proplist = [PR_ENTRYID, $properties["recurring"], $properties["recurring_data"], $properties["timezone_data"]];
Please login to merge, or discard this patch.
Braces   +5 added lines, -10 removed lines patch added patch discarded remove patch
@@ -56,8 +56,7 @@  discard block
 block discarded – undo
56 56
 				}
57 57
 			}
58 58
 		}
59
-	}
60
-	else {
59
+	} else {
61 60
 		return "NOERROR";
62 61
 	}
63 62
 
@@ -98,8 +97,7 @@  discard block
 block discarded – undo
98 97
 
99 98
 			if (substr($split[2], 0, 2) == "0x") {
100 99
 				$id = hexdec(substr($split[2], 2));
101
-			}
102
-			else {
100
+			} else {
103 101
 				$id = $split[2];
104 102
 			}
105 103
 
@@ -109,8 +107,7 @@  discard block
 block discarded – undo
109 107
 					$guids[$split[1]] = makeguid($split[1]);
110 108
 				}
111 109
 				$guid = $guids[$split[1]];
112
-			}
113
-			else {
110
+			} else {
114 111
 				$guid = constant($split[1]);
115 112
 			}
116 113
 
@@ -120,8 +117,7 @@  discard block
 block discarded – undo
120 117
 			$ids["guid"][$num] = $guid;
121 118
 			$ids["type"][$num] = $split[0];
122 119
 			++$num;
123
-		}
124
-		else {
120
+		} else {
125 121
 			// not a named property
126 122
 			$props[$name] = $val;
127 123
 		}
@@ -280,8 +276,7 @@  discard block
 block discarded – undo
280 276
 				$item = $occurrence + $row;
281 277
 				array_push($items, $item);
282 278
 			}
283
-		}
284
-		else {
279
+		} else {
285 280
 			// Normal item, it matched the search criteria and therefore overlaps the interval <$viewstart, $viewend>
286 281
 			array_push($items, $row);
287 282
 		}
Please login to merge, or discard this patch.
mapi/mapidefs.php 2 patches
Indentation   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -632,7 +632,7 @@
 block discarded – undo
632 632
 /* PersistElementType Values ElementIDs for persist data of PR_IPM_OL2007_ENTRYIDS / PR_ADDITIONAL_REN_ENTRYIDS_EX */
633 633
 define('ELEMENT_SENTINEL', 0x0000); // 0 bytes Indicates that the PersistElement structure is the last one contained in the DataElements field of the PersistData structure.
634 634
 define('RSF_ELID_ENTRYID', 0x0001); // variable Indicates that the ElementData field contains the entry ID of the special folder
635
-														   // that is of the type indicated by the value of the PersistID field of the PersistData structure.
635
+                                                            // that is of the type indicated by the value of the PersistID field of the PersistData structure.
636 636
 define('RSF_ELID_HEADER', 0x0002); // 4 bytes Indicates that the ElementData field contains a 4-byte header value equal to 0x00000000.
637 637
 
638 638
 define('STGM_DIRECT', 0x00000000);
Please login to merge, or discard this patch.
Spacing   +96 added lines, -96 removed lines patch added patch discarded remove patch
@@ -16,40 +16,40 @@  discard block
 block discarded – undo
16 16
 
17 17
 /* Object type */
18 18
 
19
-define('MAPI_STORE', 0x00000001);    /* Message Store */
20
-define('MAPI_ADDRBOOK', 0x00000002);    /* Address Book */
21
-define('MAPI_FOLDER', 0x00000003);    /* Folder */
22
-define('MAPI_ABCONT', 0x00000004);    /* Address Book Container */
23
-define('MAPI_MESSAGE', 0x00000005);    /* Message */
24
-define('MAPI_MAILUSER', 0x00000006);    /* Individual Recipient */
25
-define('MAPI_ATTACH', 0x00000007);    /* Attachment */
26
-define('MAPI_DISTLIST', 0x00000008);    /* Distribution List Recipient */
27
-define('MAPI_PROFSECT', 0x00000009);    /* Profile Section */
28
-define('MAPI_STATUS', 0x0000000A);    /* Status Object */
29
-define('MAPI_SESSION', 0x0000000B);    /* Session */
30
-define('MAPI_FORMINFO', 0x0000000C);    /* Form Information */
19
+define('MAPI_STORE', 0x00000001); /* Message Store */
20
+define('MAPI_ADDRBOOK', 0x00000002); /* Address Book */
21
+define('MAPI_FOLDER', 0x00000003); /* Folder */
22
+define('MAPI_ABCONT', 0x00000004); /* Address Book Container */
23
+define('MAPI_MESSAGE', 0x00000005); /* Message */
24
+define('MAPI_MAILUSER', 0x00000006); /* Individual Recipient */
25
+define('MAPI_ATTACH', 0x00000007); /* Attachment */
26
+define('MAPI_DISTLIST', 0x00000008); /* Distribution List Recipient */
27
+define('MAPI_PROFSECT', 0x00000009); /* Profile Section */
28
+define('MAPI_STATUS', 0x0000000A); /* Status Object */
29
+define('MAPI_SESSION', 0x0000000B); /* Session */
30
+define('MAPI_FORMINFO', 0x0000000C); /* Form Information */
31 31
 
32 32
 define('MV_FLAG', 0x1000);
33 33
 define('MV_INSTANCE', 0x2000);
34
-define('MVI_FLAG', MV_FLAG | MV_INSTANCE);
35
-
36
-define('PT_UNSPECIFIED', 0);    /* (Reserved for interface use) type doesn't matter to caller */
37
-define('PT_NULL', 1);    /* NULL property value */
38
-define('PT_I2', 2);    /* Signed 16-bit value */
39
-define('PT_LONG', 3);    /* Signed 32-bit value */
40
-define('PT_R4', 4);    /* 4-byte floating point */
41
-define('PT_DOUBLE', 5);    /* Floating point double */
42
-define('PT_CURRENCY', 6);    /* Signed 64-bit int (decimal w/    4 digits right of decimal pt) */
43
-define('PT_APPTIME', 7);    /* Application time */
44
-define('PT_ERROR', 10);    /* 32-bit error value */
45
-define('PT_BOOLEAN', 11);    /* 16-bit boolean (non-zero true) */
46
-define('PT_OBJECT', 13);    /* Embedded object in a property */
47
-define('PT_I8', 20);    /* 8-byte signed integer */
48
-define('PT_STRING8', 30);    /* Null terminated 8-bit character string */
49
-define('PT_UNICODE', 31);    /* Null terminated Unicode string */
50
-define('PT_SYSTIME', 64);    /* FILETIME 64-bit int w/ number of 100ns periods since Jan 1,1601 */
51
-define('PT_CLSID', 72);    /* OLE GUID */
52
-define('PT_BINARY', 258);   /* Uninterpreted (counted byte array) */
34
+define('MVI_FLAG', MV_FLAG|MV_INSTANCE);
35
+
36
+define('PT_UNSPECIFIED', 0); /* (Reserved for interface use) type doesn't matter to caller */
37
+define('PT_NULL', 1); /* NULL property value */
38
+define('PT_I2', 2); /* Signed 16-bit value */
39
+define('PT_LONG', 3); /* Signed 32-bit value */
40
+define('PT_R4', 4); /* 4-byte floating point */
41
+define('PT_DOUBLE', 5); /* Floating point double */
42
+define('PT_CURRENCY', 6); /* Signed 64-bit int (decimal w/    4 digits right of decimal pt) */
43
+define('PT_APPTIME', 7); /* Application time */
44
+define('PT_ERROR', 10); /* 32-bit error value */
45
+define('PT_BOOLEAN', 11); /* 16-bit boolean (non-zero true) */
46
+define('PT_OBJECT', 13); /* Embedded object in a property */
47
+define('PT_I8', 20); /* 8-byte signed integer */
48
+define('PT_STRING8', 30); /* Null terminated 8-bit character string */
49
+define('PT_UNICODE', 31); /* Null terminated Unicode string */
50
+define('PT_SYSTIME', 64); /* FILETIME 64-bit int w/ number of 100ns periods since Jan 1,1601 */
51
+define('PT_CLSID', 72); /* OLE GUID */
52
+define('PT_BINARY', 258); /* Uninterpreted (counted byte array) */
53 53
 /* Changes are likely to these numbers, and to their structures. */
54 54
 
55 55
 /* Alternate property type names for ease of use */
@@ -61,18 +61,18 @@  discard block
 block discarded – undo
61 61
 
62 62
 define('PT_TSTRING', PT_STRING8);
63 63
 
64
-define('PT_MV_I2', (MV_FLAG | PT_I2));
65
-define('PT_MV_LONG', (MV_FLAG | PT_LONG));
66
-define('PT_MV_R4', (MV_FLAG | PT_R4));
67
-define('PT_MV_DOUBLE', (MV_FLAG | PT_DOUBLE));
68
-define('PT_MV_CURRENCY', (MV_FLAG | PT_CURRENCY));
69
-define('PT_MV_APPTIME', (MV_FLAG | PT_APPTIME));
70
-define('PT_MV_SYSTIME', (MV_FLAG | PT_SYSTIME));
71
-define('PT_MV_STRING8', (MV_FLAG | PT_STRING8));
72
-define('PT_MV_BINARY', (MV_FLAG | PT_BINARY));
73
-define('PT_MV_UNICODE', (MV_FLAG | PT_UNICODE));
74
-define('PT_MV_CLSID', (MV_FLAG | PT_CLSID));
75
-define('PT_MV_I8', (MV_FLAG | PT_I8));
64
+define('PT_MV_I2', (MV_FLAG|PT_I2));
65
+define('PT_MV_LONG', (MV_FLAG|PT_LONG));
66
+define('PT_MV_R4', (MV_FLAG|PT_R4));
67
+define('PT_MV_DOUBLE', (MV_FLAG|PT_DOUBLE));
68
+define('PT_MV_CURRENCY', (MV_FLAG|PT_CURRENCY));
69
+define('PT_MV_APPTIME', (MV_FLAG|PT_APPTIME));
70
+define('PT_MV_SYSTIME', (MV_FLAG|PT_SYSTIME));
71
+define('PT_MV_STRING8', (MV_FLAG|PT_STRING8));
72
+define('PT_MV_BINARY', (MV_FLAG|PT_BINARY));
73
+define('PT_MV_UNICODE', (MV_FLAG|PT_UNICODE));
74
+define('PT_MV_CLSID', (MV_FLAG|PT_CLSID));
75
+define('PT_MV_I8', (MV_FLAG|PT_I8));
76 76
 
77 77
 define('PT_MV_TSTRING', PT_MV_STRING8);
78 78
 /* bit 0: set if descending, clear if ascending */
@@ -190,14 +190,14 @@  discard block
 block discarded – undo
190 190
 
191 191
 /* Values for PR_RESOURCE_TYPE, _METHODS, _FLAGS */
192 192
 
193
-define('MAPI_STORE_PROVIDER', 33);    /* Message Store */
194
-define('MAPI_AB', 34);    /* Address Book */
195
-define('MAPI_AB_PROVIDER', 35);    /* Address Book Provider */
196
-define('MAPI_TRANSPORT_PROVIDER', 36);    /* Transport Provider */
197
-define('MAPI_SPOOLER', 37);    /* Message Spooler */
198
-define('MAPI_PROFILE_PROVIDER', 38);    /* Profile Provider */
199
-define('MAPI_SUBSYSTEM', 39);    /* Overall Subsystem Status */
200
-define('MAPI_HOOK_PROVIDER', 40);    /* Spooler Hook */
193
+define('MAPI_STORE_PROVIDER', 33); /* Message Store */
194
+define('MAPI_AB', 34); /* Address Book */
195
+define('MAPI_AB_PROVIDER', 35); /* Address Book Provider */
196
+define('MAPI_TRANSPORT_PROVIDER', 36); /* Transport Provider */
197
+define('MAPI_SPOOLER', 37); /* Message Spooler */
198
+define('MAPI_PROFILE_PROVIDER', 38); /* Profile Provider */
199
+define('MAPI_SUBSYSTEM', 39); /* Overall Subsystem Status */
200
+define('MAPI_HOOK_PROVIDER', 40); /* Spooler Hook */
201 201
 define('STATUS_VALIDATE_STATE', 0x00000001);
202 202
 define('STATUS_SETTINGS_DIALOG', 0x00000002);
203 203
 define('STATUS_CHANGE_PASSWORD', 0x00000004);
@@ -243,10 +243,10 @@  discard block
 block discarded – undo
243 243
 define('MODRECIP_MODIFY', 0x00000004);
244 244
 define('MODRECIP_REMOVE', 0x00000008);
245 245
 
246
-define('MAPI_ORIG', 0);          /* Recipient is message originator */
247
-define('MAPI_TO', 1);          /* Recipient is a primary recipient */
248
-define('MAPI_CC', 2);          /* Recipient is a copy recipient */
249
-define('MAPI_BCC', 3);          /* Recipient is blind copy recipient */
246
+define('MAPI_ORIG', 0); /* Recipient is message originator */
247
+define('MAPI_TO', 1); /* Recipient is a primary recipient */
248
+define('MAPI_CC', 2); /* Recipient is a copy recipient */
249
+define('MAPI_BCC', 3); /* Recipient is blind copy recipient */
250 250
 
251 251
 /* IAttach Interface ------------------------------------------------------- */
252 252
 
@@ -438,23 +438,23 @@  discard block
 block discarded – undo
438 438
 define('BMR_NEZ', 0x00000001);
439 439
 
440 440
 /* array index values of restrictions -- same values are used in php-ext/main.cpp::PHPArraytoSRestriction() */
441
-define('VALUE', 0);        // propval
442
-define('RELOP', 1);        // compare method
443
-define('FUZZYLEVEL', 2);        // string search flags
444
-define('CB', 3);        // size restriction
445
-define('ULTYPE', 4);        // bit mask restriction type BMR_xxx
446
-define('ULMASK', 5);        // bitmask
447
-define('ULPROPTAG', 6);        // property
448
-define('ULPROPTAG1', 7);        // RES_COMPAREPROPS 1st property
449
-define('ULPROPTAG2', 8);        // RES_COMPAREPROPS 2nd property
450
-define('PROPS', 9);        // RES_COMMENT properties
451
-define('RESTRICTION', 10);       // RES_COMMENT and RES_SUBRESTRICTION restriction
441
+define('VALUE', 0); // propval
442
+define('RELOP', 1); // compare method
443
+define('FUZZYLEVEL', 2); // string search flags
444
+define('CB', 3); // size restriction
445
+define('ULTYPE', 4); // bit mask restriction type BMR_xxx
446
+define('ULMASK', 5); // bitmask
447
+define('ULPROPTAG', 6); // property
448
+define('ULPROPTAG1', 7); // RES_COMPAREPROPS 1st property
449
+define('ULPROPTAG2', 8); // RES_COMPAREPROPS 2nd property
450
+define('PROPS', 9); // RES_COMMENT properties
451
+define('RESTRICTION', 10); // RES_COMMENT and RES_SUBRESTRICTION restriction
452 452
 
453 453
 /* GUID's for PR_MDB_PROVIDER */
454
-define("ZARAFA_SERVICE_GUID", makeGuid("{3C253DCA-D227-443C-94FE-425FAB958C19}"));    // default store
455
-define("ZARAFA_STORE_PUBLIC_GUID", makeGuid("{70FAB278-F7AF-CD11-9BC8-00AA002FC45A}"));    // public store
456
-define("ZARAFA_STORE_DELEGATE_GUID", makeGuid("{7C7C1085-BC6D-4E53-9DAB-8A53F8DEF808}"));    // other store
457
-define('ZARAFA_STORE_ARCHIVER_GUID', makeGuid("{BC8953AD-2E3F-4172-9404-896FF459870F}"));    // archive store
454
+define("ZARAFA_SERVICE_GUID", makeGuid("{3C253DCA-D227-443C-94FE-425FAB958C19}")); // default store
455
+define("ZARAFA_STORE_PUBLIC_GUID", makeGuid("{70FAB278-F7AF-CD11-9BC8-00AA002FC45A}")); // public store
456
+define("ZARAFA_STORE_DELEGATE_GUID", makeGuid("{7C7C1085-BC6D-4E53-9DAB-8A53F8DEF808}")); // other store
457
+define('ZARAFA_STORE_ARCHIVER_GUID', makeGuid("{BC8953AD-2E3F-4172-9404-896FF459870F}")); // archive store
458 458
 
459 459
 /* global profile section guid */
460 460
 define('pbGlobalProfileSectionGuid', makeGuid("{C8B0DB13-05AA-1A10-9BB0-00AA002FC45A}"));
@@ -481,10 +481,10 @@  discard block
 block discarded – undo
481 481
 // define('ecrightsContact'                       ,0x00000200);
482 482
 define('ecRightsFolderVisible', 0x00000400);
483 483
 
484
-define('ecRightsAll', ecRightsReadAny | ecRightsCreate | ecRightsEditOwned | ecRightsDeleteOwned | ecRightsEditAny | ecRightsDeleteAny | ecRightsCreateSubfolder | ecRightsFolderAccess | ecRightsFolderVisible);
485
-define('ecRightsFullControl', ecRightsReadAny | ecRightsCreate | ecRightsEditOwned | ecRightsDeleteOwned | ecRightsEditAny | ecRightsDeleteAny | ecRightsCreateSubfolder | ecRightsFolderVisible);
486
-define('ecRightsDefault', ecRightsNone | ecRightsFolderVisible);
487
-define('ecRightsDefaultPublic', ecRightsReadAny | ecRightsFolderVisible);
484
+define('ecRightsAll', ecRightsReadAny|ecRightsCreate|ecRightsEditOwned|ecRightsDeleteOwned|ecRightsEditAny|ecRightsDeleteAny|ecRightsCreateSubfolder|ecRightsFolderAccess|ecRightsFolderVisible);
485
+define('ecRightsFullControl', ecRightsReadAny|ecRightsCreate|ecRightsEditOwned|ecRightsDeleteOwned|ecRightsEditAny|ecRightsDeleteAny|ecRightsCreateSubfolder|ecRightsFolderVisible);
486
+define('ecRightsDefault', ecRightsNone|ecRightsFolderVisible);
487
+define('ecRightsDefaultPublic', ecRightsReadAny|ecRightsFolderVisible);
488 488
 define('ecRightsAdmin', 0x00001000);
489 489
 define('ecRightsAllMask', 0x000015FB);
490 490
 
@@ -500,7 +500,7 @@  discard block
 block discarded – undo
500 500
 define('ROW_ADD', 0x0001);
501 501
 define('ROW_MODIFY', 0x0002);
502 502
 define('ROW_REMOVE', 0x0004);
503
-define('ROW_EMPTY', (ROW_ADD | ROW_REMOVE));
503
+define('ROW_EMPTY', (ROW_ADD|ROW_REMOVE));
504 504
 
505 505
 // new property types
506 506
 define('PT_SRESTRICTION', 0x00FD);
@@ -570,38 +570,38 @@  discard block
 block discarded – undo
570 570
 define('SYNC_NO_FOREIGN_KEYS', 0x100);
571 571
 define('SYNC_LIMITED_IMESSAGE', 0x200);
572 572
 define('SYNC_CATCHUP', 0x400);
573
-define('SYNC_NEW_MESSAGE', 0x800);         // only applicable to ImportMessageChange()
574
-define('SYNC_MSG_SELECTIVE', 0x1000);        // Used internally.      Will reject if used by clients.
573
+define('SYNC_NEW_MESSAGE', 0x800); // only applicable to ImportMessageChange()
574
+define('SYNC_MSG_SELECTIVE', 0x1000); // Used internally.      Will reject if used by clients.
575 575
 define('SYNC_BEST_BODY', 0x2000);
576 576
 define('SYNC_IGNORE_SPECIFIED_ON_ASSOCIATED', 0x4000);
577
-define('SYNC_PROGRESS_MODE', 0x8000);        // AirMapi progress mode
577
+define('SYNC_PROGRESS_MODE', 0x8000); // AirMapi progress mode
578 578
 define('SYNC_FXRECOVERMODE', 0x10000);
579 579
 define('SYNC_DEFER_CONFIG', 0x20000);
580
-define('SYNC_FORCE_UNICODE', 0x40000);       // Forces server to return Unicode properties
581
-define('SYNC_STATE_READONLY', 0x80000);       // Server will not update the states in the DB, setting up exporter with this flag states are read only
580
+define('SYNC_FORCE_UNICODE', 0x40000); // Forces server to return Unicode properties
581
+define('SYNC_STATE_READONLY', 0x80000); // Server will not update the states in the DB, setting up exporter with this flag states are read only
582 582
 
583
-define('EMS_AB_ADDRESS_LOOKUP', 0x00000001);    // Flag for resolvename to resolve only exact matches
583
+define('EMS_AB_ADDRESS_LOOKUP', 0x00000001); // Flag for resolvename to resolve only exact matches
584 584
 
585
-define('TBL_BATCH', 0x00000002);    // Batch multiple table commands
585
+define('TBL_BATCH', 0x00000002); // Batch multiple table commands
586 586
 
587 587
 /* Flags for recipients in exceptions */
588
-define('recipSendable', 0x00000001);    // sendable attendee.
589
-define('recipOrganizer', 0x00000002);    // meeting organizer
590
-define('recipExceptionalResponse', 0x00000010);    // attendee gave a response for the exception
591
-define('recipExceptionalDeleted', 0x00000020);    // recipientRow exists, but it is treated as if the corresponding recipient is deleted from meeting
592
-define('recipOriginal', 0x00000100);    // recipient is an original Attendee
588
+define('recipSendable', 0x00000001); // sendable attendee.
589
+define('recipOrganizer', 0x00000002); // meeting organizer
590
+define('recipExceptionalResponse', 0x00000010); // attendee gave a response for the exception
591
+define('recipExceptionalDeleted', 0x00000020); // recipientRow exists, but it is treated as if the corresponding recipient is deleted from meeting
592
+define('recipOriginal', 0x00000100); // recipient is an original Attendee
593 593
 define('recipReserved', 0x00000200);
594 594
 
595 595
 /* Flags which indicates type of Meeting Object */
596
-define('mtgEmpty', 0x00000000);    // Unspecified.
597
-define('mtgRequest', 0x00000001);    // Initial meeting request.
598
-define('mtgFull', 0x00010000);    // Full update.
599
-define('mtgInfo', 0x00020000);    // Informational update.
600
-define('mtgOutOfDate', 0x00080000);    // A newer Meeting Request object or Meeting Update object was received after this one.
601
-define('mtgDelegatorCopy', 0x00100000);    // This is set on the delegator's copy when a delegate will handle meeting-related objects.
602
-
603
-define('MAPI_ONE_OFF_UNICODE', 0x8000);        // the flag that defines whether the embedded strings are Unicode in one off entryids.
604
-define('MAPI_ONE_OFF_NO_RICH_INFO', 0x0001);        // the flag that specifies whether the recipient gets TNEF or not.
596
+define('mtgEmpty', 0x00000000); // Unspecified.
597
+define('mtgRequest', 0x00000001); // Initial meeting request.
598
+define('mtgFull', 0x00010000); // Full update.
599
+define('mtgInfo', 0x00020000); // Informational update.
600
+define('mtgOutOfDate', 0x00080000); // A newer Meeting Request object or Meeting Update object was received after this one.
601
+define('mtgDelegatorCopy', 0x00100000); // This is set on the delegator's copy when a delegate will handle meeting-related objects.
602
+
603
+define('MAPI_ONE_OFF_UNICODE', 0x8000); // the flag that defines whether the embedded strings are Unicode in one off entryids.
604
+define('MAPI_ONE_OFF_NO_RICH_INFO', 0x0001); // the flag that specifies whether the recipient gets TNEF or not.
605 605
 
606 606
 /* Mask flags for mapi_msgstore_advise */
607 607
 define('fnevCriticalError', 0x00000001);
Please login to merge, or discard this patch.
mapi/class.taskrequest.php 3 patches
Indentation   +1219 added lines, -1219 removed lines patch added patch discarded remove patch
@@ -4,7 +4,7 @@  discard block
 block discarded – undo
4 4
  * SPDX-FileCopyrightText: Copyright 2005-2016 Zarafa Deutschland GmbH
5 5
  * SPDX-FileCopyrightText: Copyright 2020-2022 grommunio GmbH
6 6
  */
7
-	/*
7
+    /*
8 8
 	* In general
9 9
 	*
10 10
 	* This class never actually modifies a task item unless we receive a task request update. This means
@@ -16,93 +16,93 @@  discard block
 block discarded – undo
16 16
 	* task request is sent via sendTaskRequest.
17 17
 	*/
18 18
 
19
-	/* The TaskMode value is only used for the IPM.TaskRequest items.
19
+    /* The TaskMode value is only used for the IPM.TaskRequest items.
20 20
 	 * It must 0 (tdmtNothing) on IPM.Task items.
21 21
 	 *
22 22
 	 * It is used to indicate the type of change that is being
23 23
 	 * carried in the IPM.TaskRequest item (although this information seems
24 24
 	 * redundant due to that information already being available in PR_MESSAGE_CLASS).
25 25
 	 */
26
-	define('tdmtNothing', 0);            // Value in IPM.Task items
27
-	define('tdmtTaskReq', 1);            // Assigner -> Assignee
28
-	define('tdmtTaskAcc', 2);            // Assignee -> Assigner
29
-	define('tdmtTaskDec', 3);            // Assignee -> Assigner
30
-	define('tdmtTaskUpd', 4);            // Assignee -> Assigner
31
-	define('tdmtTaskSELF', 5);            // Assigner -> Assigner (?)
32
-
33
-	/* The TaskHistory is used to show the last action on the task
26
+    define('tdmtNothing', 0);            // Value in IPM.Task items
27
+    define('tdmtTaskReq', 1);            // Assigner -> Assignee
28
+    define('tdmtTaskAcc', 2);            // Assignee -> Assigner
29
+    define('tdmtTaskDec', 3);            // Assignee -> Assigner
30
+    define('tdmtTaskUpd', 4);            // Assignee -> Assigner
31
+    define('tdmtTaskSELF', 5);            // Assigner -> Assigner (?)
32
+
33
+    /* The TaskHistory is used to show the last action on the task
34 34
 	 * on both the assigner and the assignee's side.
35 35
 	 *
36 36
 	 * It is used in combination with 'task_assigned_time' and 'tasklastdelegate'
37 37
 	 * or 'tasklastuser' to show the information at the top of the task request in
38 38
 	 * the format 'Accepted by <user> on 01-01-2010 11:00'.
39 39
 	 */
40
-	define('thNone', 0);
41
-	define('thAccepted', 1);            // Set by assignee
42
-	define('thDeclined', 2);            // Set by assignee
43
-	define('thUpdated', 3);                // Set by assignee
44
-	define('thDueDateChanged', 4);
45
-	define('thAssigned', 5);            // Set by assigner
46
-
47
-	/* The TaskState value is used to differentiate the version of a task
40
+    define('thNone', 0);
41
+    define('thAccepted', 1);            // Set by assignee
42
+    define('thDeclined', 2);            // Set by assignee
43
+    define('thUpdated', 3);                // Set by assignee
44
+    define('thDueDateChanged', 4);
45
+    define('thAssigned', 5);            // Set by assigner
46
+
47
+    /* The TaskState value is used to differentiate the version of a task
48 48
 	 * in the assigner's folder and the version in the
49 49
 	 * assignee's folder. The buttons shown depend on this and
50 50
 	 * the 'taskaccepted' boolean (for the assignee)
51 51
 	 */
52
-	define('tdsNOM', 0);        // Got a response to a deleted task, and re-created the task for the assigner
53
-	define('tdsOWNNEW', 1);        // Not assigned
54
-	define('tdsOWN', 2);        // Assignee version
55
-	define('tdsACC', 3);        // Assigner version
56
-	define('tdsDEC', 4);        // Assigner version, but assignee declined
57
-
58
-	/* The TaskAcceptanceState is used for the assigner to indicate state */
59
-	define('olTaskNotDelegated', 0);
60
-	define('olTaskDelegationUnknown', 1); // After sending req
61
-	define('olTaskDelegationAccepted', 2); // After receiving accept
62
-	define('olTaskDelegationDeclined', 3); // After receiving decline
63
-
64
-	/* The task ownership indicates the role of the current user relative to the task. */
65
-	define('olNewTask', 0);
66
-	define('olDelegatedTask', 1);    // Task has been assigned
67
-	define('olOwnTask', 2);            // Task owned
68
-
69
-	/* taskmultrecips indicates whether the task request sent or received has multiple assignees or not. */
70
-	define('tmrNone', 0);
71
-	define('tmrSent', 1);        // Task has been sent to multiple assignee
72
-	define('tmrReceived', 2);    // Task Request received has multiple assignee
73
-
74
-	// Task icon index.
75
-	define('ICON_TASK_ASSIGNEE', 0x00000502);
76
-	define('ICON_TASK_DECLINE', 0x00000506);
77
-	define('ICON_TASK_ASSIGNER', 0x00000503);
78
-
79
-	class TaskRequest {
80
-		private $props;
81
-		private $store;
82
-		private $message;
83
-		private $session;
84
-		private $taskCommentsInfo;
85
-
86
-		// All recipient properties
87
-		public $recipProps = [
88
-			PR_ENTRYID,
89
-			PR_DISPLAY_NAME,
90
-			PR_EMAIL_ADDRESS,
91
-			PR_RECIPIENT_ENTRYID,
92
-			PR_RECIPIENT_TYPE,
93
-			PR_SEND_INTERNET_ENCODING,
94
-			PR_SEND_RICH_INFO,
95
-			PR_RECIPIENT_DISPLAY_NAME,
96
-			PR_ADDRTYPE,
97
-			PR_DISPLAY_TYPE,
98
-			PR_RECIPIENT_TRACKSTATUS,
99
-			PR_RECIPIENT_TRACKSTATUS_TIME,
100
-			PR_RECIPIENT_FLAGS,
101
-			PR_ROWID,
102
-			PR_SEARCH_KEY,
103
-		];
104
-
105
-		/* Constructor
52
+    define('tdsNOM', 0);        // Got a response to a deleted task, and re-created the task for the assigner
53
+    define('tdsOWNNEW', 1);        // Not assigned
54
+    define('tdsOWN', 2);        // Assignee version
55
+    define('tdsACC', 3);        // Assigner version
56
+    define('tdsDEC', 4);        // Assigner version, but assignee declined
57
+
58
+    /* The TaskAcceptanceState is used for the assigner to indicate state */
59
+    define('olTaskNotDelegated', 0);
60
+    define('olTaskDelegationUnknown', 1); // After sending req
61
+    define('olTaskDelegationAccepted', 2); // After receiving accept
62
+    define('olTaskDelegationDeclined', 3); // After receiving decline
63
+
64
+    /* The task ownership indicates the role of the current user relative to the task. */
65
+    define('olNewTask', 0);
66
+    define('olDelegatedTask', 1);    // Task has been assigned
67
+    define('olOwnTask', 2);            // Task owned
68
+
69
+    /* taskmultrecips indicates whether the task request sent or received has multiple assignees or not. */
70
+    define('tmrNone', 0);
71
+    define('tmrSent', 1);        // Task has been sent to multiple assignee
72
+    define('tmrReceived', 2);    // Task Request received has multiple assignee
73
+
74
+    // Task icon index.
75
+    define('ICON_TASK_ASSIGNEE', 0x00000502);
76
+    define('ICON_TASK_DECLINE', 0x00000506);
77
+    define('ICON_TASK_ASSIGNER', 0x00000503);
78
+
79
+    class TaskRequest {
80
+        private $props;
81
+        private $store;
82
+        private $message;
83
+        private $session;
84
+        private $taskCommentsInfo;
85
+
86
+        // All recipient properties
87
+        public $recipProps = [
88
+            PR_ENTRYID,
89
+            PR_DISPLAY_NAME,
90
+            PR_EMAIL_ADDRESS,
91
+            PR_RECIPIENT_ENTRYID,
92
+            PR_RECIPIENT_TYPE,
93
+            PR_SEND_INTERNET_ENCODING,
94
+            PR_SEND_RICH_INFO,
95
+            PR_RECIPIENT_DISPLAY_NAME,
96
+            PR_ADDRTYPE,
97
+            PR_DISPLAY_TYPE,
98
+            PR_RECIPIENT_TRACKSTATUS,
99
+            PR_RECIPIENT_TRACKSTATUS_TIME,
100
+            PR_RECIPIENT_FLAGS,
101
+            PR_ROWID,
102
+            PR_SEARCH_KEY,
103
+        ];
104
+
105
+        /* Constructor
106 106
 		 *
107 107
 		 * Constructs a TaskRequest object for the specified message. This can be either the task request
108 108
 		 * message itself (in the inbox) or the task in the tasks folder, depending on the action to be performed.
@@ -114,582 +114,582 @@  discard block
 block discarded – undo
114 114
 		 * @param $message message MAPI Message to which the task request refers to (can be an email or a task)
115 115
 		 * @param $session session MAPI Session which is used to open tasks folders for delegated task requests or responses
116 116
 		 */
117
-		public function __construct($store, $message, $session) {
118
-			$this->store = $store;
119
-			$this->message = $message;
120
-			$this->session = $session;
121
-			$this->taskCommentsInfo = false;
122
-
123
-			$properties["owner"] = "PT_STRING8:PSETID_Task:0x811f";
124
-			$properties["updatecount"] = "PT_LONG:PSETID_Task:0x8112";
125
-			$properties["taskstate"] = "PT_LONG:PSETID_Task:0x8113";
126
-			$properties["taskmultrecips"] = "PT_LONG:PSETID_Task:0x8120";
127
-			$properties["taskupdates"] = "PT_BOOLEAN:PSETID_Task:0x811b";
128
-			$properties["tasksoc"] = "PT_BOOLEAN:PSETID_Task:0x8119";
129
-			$properties["taskhistory"] = "PT_LONG:PSETID_Task:0x811a";
130
-			$properties["taskmode"] = "PT_LONG:PSETID_Common:0x8518";
131
-			$properties["task_goid"] = "PT_BINARY:PSETID_Common:0x8519";
132
-			$properties["complete"] = "PT_BOOLEAN:PSETID_Common:0x811c";
133
-			$properties["task_assigned_time"] = "PT_SYSTIME:PSETID_Task:0x8115";
134
-			$properties["taskfcreator"] = "PT_BOOLEAN:PSETID_Task:0x0x811e";
135
-			$properties["tasklastuser"] = "PT_STRING8:PSETID_Task:0x8122";
136
-			$properties["tasklastdelegate"] = "PT_STRING8:PSETID_Task:0x8125";
137
-			$properties["taskaccepted"] = "PT_BOOLEAN:PSETID_Task:0x8108";
138
-			$properties["task_acceptance_state"] = "PT_LONG:PSETID_Task:0x812a";
139
-			$properties["ownership"] = "PT_LONG:PSETID_Task:0x8129";
140
-
141
-			$properties["complete"] = "PT_BOOLEAN:PSETID_Task:0x811c";
142
-			$properties["datecompleted"] = "PT_SYSTIME:PSETID_Task:0x810f";
143
-			$properties["recurring"] = "PT_BOOLEAN:PSETID_Task:0x8126";
144
-			$properties["startdate"] = "PT_SYSTIME:PSETID_Task:0x8104";
145
-			$properties["duedate"] = "PT_SYSTIME:PSETID_Task:0x8105";
146
-			$properties["status"] = "PT_LONG:PSETID_Task:0x8101";
147
-			$properties["percent_complete"] = "PT_DOUBLE:PSETID_Task:0x8102";
148
-			$properties["totalwork"] = "PT_LONG:PSETID_Task:0x8111";
149
-			$properties["actualwork"] = "PT_LONG:PSETID_Task:0x8110";
150
-			$properties["categories"] = "PT_MV_STRING8:PS_PUBLIC_STRINGS:Keywords";
151
-			$properties["companies"] = "PT_MV_STRING8:PSETID_Common:0x8539";
152
-			$properties["mileage"] = "PT_STRING8:PSETID_Common:0x8534";
153
-			$properties["billinginformation"] = "PT_STRING8:PSETID_Common:0x8535";
154
-
155
-			$this->props = getPropIdsFromStrings($store, $properties);
156
-		}
157
-
158
-		// General functions
159
-
160
-		/**
161
-		 * Returns TRUE if the message pointed to is an incoming task request and should
162
-		 * therefore be replied to with doAccept or doDecline().
163
-		 *
164
-		 * @param string $messageClass message class to use for checking
165
-		 *
166
-		 * @return bool returns true if this is a task request else false
167
-		 */
168
-		public function isTaskRequest($messageClass = false) {
169
-			if ($messageClass === false) {
170
-				$props = mapi_getprops($this->message, [PR_MESSAGE_CLASS]);
171
-				$messageClass = isset($props[PR_MESSAGE_CLASS]) ? $props[PR_MESSAGE_CLASS] : false;
172
-			}
173
-
174
-			if ($messageClass !== false && $messageClass === "IPM.TaskRequest") {
175
-				return true;
176
-			}
177
-
178
-			return false;
179
-		}
180
-
181
-		/**
182
-		 * Returns TRUE if the message pointed to is a returning task request response.
183
-		 *
184
-		 * @param string $messageClass message class to use for checking
185
-		 *
186
-		 * @return bool returns true if this is a task request else false
187
-		 */
188
-		public function isTaskRequestResponse($messageClass = false) {
189
-			if ($messageClass === false) {
190
-				$props = mapi_getprops($this->message, [PR_MESSAGE_CLASS]);
191
-				$messageClass = isset($props[PR_MESSAGE_CLASS]) ? $props[PR_MESSAGE_CLASS] : false;
192
-			}
193
-
194
-			if ($messageClass !== false && strpos($messageClass, "IPM.TaskRequest.") === 0) {
195
-				return true;
196
-			}
197
-
198
-			return false;
199
-		}
200
-
201
-		/**
202
-		 * Returns TRUE if the message pointed to is an incoming task request/response.
203
-		 *
204
-		 * @param array $props The MAPI properties to check message is an incoming task request/response
205
-		 *
206
-		 * @return bool Returns true if this is an incoming task request/response. else false.
207
-		 */
208
-		public function isReceivedItem($props) {
209
-			return isset($props[PR_MESSAGE_TO_ME]) ? $props[PR_MESSAGE_TO_ME] : false;
210
-		}
211
-
212
-		/**
213
-		 * Gets the task associated with an IPM.TaskRequest message.
214
-		 *
215
-		 * If the task does not exist yet, it is created, using the attachment object in the
216
-		 * task request item.
217
-		 *
218
-		 * @param bool $create false to find the associated task in user's task folder. true to
219
-		 *                     create task in user's task folder if task is not exist in task folder.
220
-		 *
221
-		 * @return false|MAPIMessage Return associated task of task request else false
222
-		 */
223
-		public function getAssociatedTask($create) {
224
-			$props = mapi_getprops($this->message, [PR_MESSAGE_CLASS, $this->props['task_goid']]);
225
-
226
-			if ($props[PR_MESSAGE_CLASS] == "IPM.Task") {
227
-				// Message itself is task, so return that
228
-				return $this->message;
229
-			}
230
-
231
-			$taskFolder = $this->getDefaultTasksFolder();
232
-			$goid = $props[$this->props['task_goid']];
233
-
234
-			// Find the task by looking for the task_goid
235
-			$restriction = [
236
-				RES_PROPERTY,
237
-				[
238
-					RELOP => RELOP_EQ,
239
-					ULPROPTAG => $this->props['task_goid'],
240
-					VALUE => $goid,
241
-				],
242
-			];
243
-
244
-			$contents = mapi_folder_getcontentstable($taskFolder);
245
-
246
-			$rows = mapi_table_queryallrows($contents, [PR_ENTRYID], $restriction);
247
-
248
-			if (empty($rows)) {
249
-				// None found, create one if possible
250
-				if (!$create) {
251
-					return false;
252
-				}
253
-
254
-				$task = mapi_folder_createmessage($taskFolder);
255
-
256
-				$sub = $this->getEmbeddedTask($this->message);
257
-				mapi_copyto($sub, [], [$this->props['categories']], $task);
258
-
259
-				$senderProps = [
260
-					PR_SENT_REPRESENTING_NAME,
261
-					PR_SENT_REPRESENTING_EMAIL_ADDRESS,
262
-					PR_SENT_REPRESENTING_ENTRYID,
263
-					PR_SENT_REPRESENTING_ADDRTYPE,
264
-					PR_SENT_REPRESENTING_SEARCH_KEY,
265
-					PR_SENDER_NAME,
266
-					PR_SENDER_EMAIL_ADDRESS,
267
-					PR_SENDER_ENTRYID,
268
-					PR_SENDER_ADDRTYPE,
269
-					PR_SENDER_SEARCH_KEY, ];
270
-
271
-				// Copy sender information from the e-mail
272
-				$props = mapi_getprops($this->message, $senderProps);
273
-				mapi_setprops($task, $props);
274
-			}
275
-			else {
276
-				// If there are multiple, just use the first
277
-				$entryid = $rows[0][PR_ENTRYID];
278
-
279
-				$store = $this->getTaskFolderStore();
280
-				$task = mapi_msgstore_openentry($store, $entryid);
281
-			}
282
-
283
-			return $task;
284
-		}
285
-
286
-		/**
287
-		 * Function which checks that if we have received a task request/response
288
-		 * for an already updated task in task folder.
289
-		 *
290
-		 * @return bool true if task request is updated later
291
-		 */
292
-		public function isTaskRequestUpdated() {
293
-			$props = mapi_getprops($this->message, [PR_MESSAGE_CLASS, $this->props['task_goid'], $this->props['updatecount']]);
294
-			$result = false;
295
-			$associatedTask = $this->getAssociatedTask(false);
296
-			if ($this->isTaskRequest($props[PR_MESSAGE_CLASS])) {
297
-				if ($associatedTask) {
298
-					return true;
299
-				}
300
-				$folder = $this->getDefaultTasksFolder();
301
-				$goid = $props[$this->props['task_goid']];
302
-
303
-				// Find the task by looking for the task_goid
304
-				$restriction = [RES_PROPERTY, [
305
-					RELOP => RELOP_EQ,
306
-					ULPROPTAG => $this->props['task_goid'],
307
-					VALUE => $goid, ],
308
-				];
309
-
310
-				$table = mapi_folder_getcontentstable($folder, MAPI_DEFERRED_ERRORS | SHOW_SOFT_DELETES);
311
-				$softDeletedItems = mapi_table_queryallrows($table, [PR_ENTRYID], $restriction);
312
-				if (!empty($softDeletedItems)) {
313
-					return true;
314
-				}
315
-			}
316
-
317
-			if ($associatedTask !== false) {
318
-				$taskItemProps = mapi_getprops($associatedTask, [$this->props['updatecount']]);
319
-				/*
117
+        public function __construct($store, $message, $session) {
118
+            $this->store = $store;
119
+            $this->message = $message;
120
+            $this->session = $session;
121
+            $this->taskCommentsInfo = false;
122
+
123
+            $properties["owner"] = "PT_STRING8:PSETID_Task:0x811f";
124
+            $properties["updatecount"] = "PT_LONG:PSETID_Task:0x8112";
125
+            $properties["taskstate"] = "PT_LONG:PSETID_Task:0x8113";
126
+            $properties["taskmultrecips"] = "PT_LONG:PSETID_Task:0x8120";
127
+            $properties["taskupdates"] = "PT_BOOLEAN:PSETID_Task:0x811b";
128
+            $properties["tasksoc"] = "PT_BOOLEAN:PSETID_Task:0x8119";
129
+            $properties["taskhistory"] = "PT_LONG:PSETID_Task:0x811a";
130
+            $properties["taskmode"] = "PT_LONG:PSETID_Common:0x8518";
131
+            $properties["task_goid"] = "PT_BINARY:PSETID_Common:0x8519";
132
+            $properties["complete"] = "PT_BOOLEAN:PSETID_Common:0x811c";
133
+            $properties["task_assigned_time"] = "PT_SYSTIME:PSETID_Task:0x8115";
134
+            $properties["taskfcreator"] = "PT_BOOLEAN:PSETID_Task:0x0x811e";
135
+            $properties["tasklastuser"] = "PT_STRING8:PSETID_Task:0x8122";
136
+            $properties["tasklastdelegate"] = "PT_STRING8:PSETID_Task:0x8125";
137
+            $properties["taskaccepted"] = "PT_BOOLEAN:PSETID_Task:0x8108";
138
+            $properties["task_acceptance_state"] = "PT_LONG:PSETID_Task:0x812a";
139
+            $properties["ownership"] = "PT_LONG:PSETID_Task:0x8129";
140
+
141
+            $properties["complete"] = "PT_BOOLEAN:PSETID_Task:0x811c";
142
+            $properties["datecompleted"] = "PT_SYSTIME:PSETID_Task:0x810f";
143
+            $properties["recurring"] = "PT_BOOLEAN:PSETID_Task:0x8126";
144
+            $properties["startdate"] = "PT_SYSTIME:PSETID_Task:0x8104";
145
+            $properties["duedate"] = "PT_SYSTIME:PSETID_Task:0x8105";
146
+            $properties["status"] = "PT_LONG:PSETID_Task:0x8101";
147
+            $properties["percent_complete"] = "PT_DOUBLE:PSETID_Task:0x8102";
148
+            $properties["totalwork"] = "PT_LONG:PSETID_Task:0x8111";
149
+            $properties["actualwork"] = "PT_LONG:PSETID_Task:0x8110";
150
+            $properties["categories"] = "PT_MV_STRING8:PS_PUBLIC_STRINGS:Keywords";
151
+            $properties["companies"] = "PT_MV_STRING8:PSETID_Common:0x8539";
152
+            $properties["mileage"] = "PT_STRING8:PSETID_Common:0x8534";
153
+            $properties["billinginformation"] = "PT_STRING8:PSETID_Common:0x8535";
154
+
155
+            $this->props = getPropIdsFromStrings($store, $properties);
156
+        }
157
+
158
+        // General functions
159
+
160
+        /**
161
+         * Returns TRUE if the message pointed to is an incoming task request and should
162
+         * therefore be replied to with doAccept or doDecline().
163
+         *
164
+         * @param string $messageClass message class to use for checking
165
+         *
166
+         * @return bool returns true if this is a task request else false
167
+         */
168
+        public function isTaskRequest($messageClass = false) {
169
+            if ($messageClass === false) {
170
+                $props = mapi_getprops($this->message, [PR_MESSAGE_CLASS]);
171
+                $messageClass = isset($props[PR_MESSAGE_CLASS]) ? $props[PR_MESSAGE_CLASS] : false;
172
+            }
173
+
174
+            if ($messageClass !== false && $messageClass === "IPM.TaskRequest") {
175
+                return true;
176
+            }
177
+
178
+            return false;
179
+        }
180
+
181
+        /**
182
+         * Returns TRUE if the message pointed to is a returning task request response.
183
+         *
184
+         * @param string $messageClass message class to use for checking
185
+         *
186
+         * @return bool returns true if this is a task request else false
187
+         */
188
+        public function isTaskRequestResponse($messageClass = false) {
189
+            if ($messageClass === false) {
190
+                $props = mapi_getprops($this->message, [PR_MESSAGE_CLASS]);
191
+                $messageClass = isset($props[PR_MESSAGE_CLASS]) ? $props[PR_MESSAGE_CLASS] : false;
192
+            }
193
+
194
+            if ($messageClass !== false && strpos($messageClass, "IPM.TaskRequest.") === 0) {
195
+                return true;
196
+            }
197
+
198
+            return false;
199
+        }
200
+
201
+        /**
202
+         * Returns TRUE if the message pointed to is an incoming task request/response.
203
+         *
204
+         * @param array $props The MAPI properties to check message is an incoming task request/response
205
+         *
206
+         * @return bool Returns true if this is an incoming task request/response. else false.
207
+         */
208
+        public function isReceivedItem($props) {
209
+            return isset($props[PR_MESSAGE_TO_ME]) ? $props[PR_MESSAGE_TO_ME] : false;
210
+        }
211
+
212
+        /**
213
+         * Gets the task associated with an IPM.TaskRequest message.
214
+         *
215
+         * If the task does not exist yet, it is created, using the attachment object in the
216
+         * task request item.
217
+         *
218
+         * @param bool $create false to find the associated task in user's task folder. true to
219
+         *                     create task in user's task folder if task is not exist in task folder.
220
+         *
221
+         * @return false|MAPIMessage Return associated task of task request else false
222
+         */
223
+        public function getAssociatedTask($create) {
224
+            $props = mapi_getprops($this->message, [PR_MESSAGE_CLASS, $this->props['task_goid']]);
225
+
226
+            if ($props[PR_MESSAGE_CLASS] == "IPM.Task") {
227
+                // Message itself is task, so return that
228
+                return $this->message;
229
+            }
230
+
231
+            $taskFolder = $this->getDefaultTasksFolder();
232
+            $goid = $props[$this->props['task_goid']];
233
+
234
+            // Find the task by looking for the task_goid
235
+            $restriction = [
236
+                RES_PROPERTY,
237
+                [
238
+                    RELOP => RELOP_EQ,
239
+                    ULPROPTAG => $this->props['task_goid'],
240
+                    VALUE => $goid,
241
+                ],
242
+            ];
243
+
244
+            $contents = mapi_folder_getcontentstable($taskFolder);
245
+
246
+            $rows = mapi_table_queryallrows($contents, [PR_ENTRYID], $restriction);
247
+
248
+            if (empty($rows)) {
249
+                // None found, create one if possible
250
+                if (!$create) {
251
+                    return false;
252
+                }
253
+
254
+                $task = mapi_folder_createmessage($taskFolder);
255
+
256
+                $sub = $this->getEmbeddedTask($this->message);
257
+                mapi_copyto($sub, [], [$this->props['categories']], $task);
258
+
259
+                $senderProps = [
260
+                    PR_SENT_REPRESENTING_NAME,
261
+                    PR_SENT_REPRESENTING_EMAIL_ADDRESS,
262
+                    PR_SENT_REPRESENTING_ENTRYID,
263
+                    PR_SENT_REPRESENTING_ADDRTYPE,
264
+                    PR_SENT_REPRESENTING_SEARCH_KEY,
265
+                    PR_SENDER_NAME,
266
+                    PR_SENDER_EMAIL_ADDRESS,
267
+                    PR_SENDER_ENTRYID,
268
+                    PR_SENDER_ADDRTYPE,
269
+                    PR_SENDER_SEARCH_KEY, ];
270
+
271
+                // Copy sender information from the e-mail
272
+                $props = mapi_getprops($this->message, $senderProps);
273
+                mapi_setprops($task, $props);
274
+            }
275
+            else {
276
+                // If there are multiple, just use the first
277
+                $entryid = $rows[0][PR_ENTRYID];
278
+
279
+                $store = $this->getTaskFolderStore();
280
+                $task = mapi_msgstore_openentry($store, $entryid);
281
+            }
282
+
283
+            return $task;
284
+        }
285
+
286
+        /**
287
+         * Function which checks that if we have received a task request/response
288
+         * for an already updated task in task folder.
289
+         *
290
+         * @return bool true if task request is updated later
291
+         */
292
+        public function isTaskRequestUpdated() {
293
+            $props = mapi_getprops($this->message, [PR_MESSAGE_CLASS, $this->props['task_goid'], $this->props['updatecount']]);
294
+            $result = false;
295
+            $associatedTask = $this->getAssociatedTask(false);
296
+            if ($this->isTaskRequest($props[PR_MESSAGE_CLASS])) {
297
+                if ($associatedTask) {
298
+                    return true;
299
+                }
300
+                $folder = $this->getDefaultTasksFolder();
301
+                $goid = $props[$this->props['task_goid']];
302
+
303
+                // Find the task by looking for the task_goid
304
+                $restriction = [RES_PROPERTY, [
305
+                    RELOP => RELOP_EQ,
306
+                    ULPROPTAG => $this->props['task_goid'],
307
+                    VALUE => $goid, ],
308
+                ];
309
+
310
+                $table = mapi_folder_getcontentstable($folder, MAPI_DEFERRED_ERRORS | SHOW_SOFT_DELETES);
311
+                $softDeletedItems = mapi_table_queryallrows($table, [PR_ENTRYID], $restriction);
312
+                if (!empty($softDeletedItems)) {
313
+                    return true;
314
+                }
315
+            }
316
+
317
+            if ($associatedTask !== false) {
318
+                $taskItemProps = mapi_getprops($associatedTask, [$this->props['updatecount']]);
319
+                /*
320 320
 				 * if(message_counter < task_counter) task object is newer then task response (task is updated)
321 321
 				 * if(message_counter >= task_counter) task is not updated, do normal processing
322 322
 				 */
323
-				if (isset($taskItemProps[$this->props['updatecount']], $props[$this->props['updatecount']])) {
324
-					if ($props[$this->props['updatecount']] < $taskItemProps[$this->props['updatecount']]) {
325
-						$result = true;
326
-					}
327
-				}
328
-			}
329
-
330
-			return $result;
331
-		}
332
-
333
-		// Organizer functions (called by the organizer)
334
-
335
-		/**
336
-		 * Processes a task request response, which can be any of the following:
337
-		 * - Task accept (task history is marked as accepted)
338
-		 * - Task decline (task history is marked as declined)
339
-		 * - Task update (updates completion %, etc).
340
-		 */
341
-		public function processTaskResponse() {
342
-			$messageProps = mapi_getprops($this->message, [PR_PROCESSED, $this->props["taskupdates"], PR_MESSAGE_TO_ME]);
343
-			if (isset($messageProps[PR_PROCESSED]) && $messageProps[PR_PROCESSED]) {
344
-				return true;
345
-			}
346
-			mapi_setprops($this->message, [PR_PROCESSED => true]);
347
-			mapi_savechanges($this->message);
348
-
349
-			// Get the embedded task information.
350
-			$sub = $this->getEmbeddedTask($this->message);
351
-
352
-			// If task is updated in task folder then we don't need to process
353
-			// old response
354
-			if ($this->isTaskRequestUpdated()) {
355
-				return true;
356
-			}
357
-
358
-			$isReceivedItem = $this->isReceivedItem($messageProps);
359
-
360
-			$isCreateAssociatedTask = false;
361
-			$isAllowUpdateAssociatedTask = $messageProps[$this->props["taskupdates"]];
362
-			$props = mapi_getprops($this->message, [PR_MESSAGE_CLASS]);
363
-			// Set correct taskmode and taskhistory depending on response type
364
-			switch ($props[PR_MESSAGE_CLASS]) {
365
-				case 'IPM.TaskRequest.Accept':
366
-					$taskHistory = thAccepted;
367
-					$taskState = $isReceivedItem ? tdsACC : tdsOWN;
368
-					$taskOwner = $isReceivedItem ? olDelegatedTask : olOwnTask;
369
-					$taskAcceptanceState = $isReceivedItem ? olTaskDelegationAccepted : olTaskNotDelegated;
370
-
371
-					break;
372
-
373
-				case 'IPM.TaskRequest.Decline':
374
-					$isCreateAssociatedTask = $isReceivedItem;
375
-					$isAllowUpdateAssociatedTask = $isReceivedItem;
376
-					$taskHistory = thDeclined;
377
-					$taskState = $isReceivedItem ? tdsDEC : tdsACC;
378
-					$taskOwner = $isReceivedItem ? olOwnTask : olDelegatedTask;
379
-					$taskAcceptanceState = $isReceivedItem ? olTaskDelegationDeclined : olTaskDelegationUnknown;
380
-
381
-					break;
382
-
383
-				case 'IPM.TaskRequest.Update':
384
-				case 'IPM.TaskRequest.Complete':
385
-					$taskHistory = thUpdated;
386
-					$taskState = $isReceivedItem ? tdsACC : tdsOWN;
387
-					$taskAcceptanceState = olTaskNotDelegated;
388
-					$taskOwner = $isReceivedItem ? olDelegatedTask : olOwnTask;
389
-
390
-					break;
391
-			}
392
-
393
-			$props = [
394
-				$this->props['taskhistory'] => $taskHistory,
395
-				$this->props['taskstate'] => $taskState,
396
-				$this->props['task_acceptance_state'] => $taskAcceptanceState,
397
-				$this->props['ownership'] => $taskOwner,
398
-			];
399
-
400
-			// Get the task for this response
401
-			$task = $this->getAssociatedTask($isCreateAssociatedTask);
402
-			if ($task && $isAllowUpdateAssociatedTask) {
403
-				// To avoid duplication of attachments in associated task. we simple remove the
404
-				// all attachments from associated task.
405
-				$taskAttachTable = mapi_message_getattachmenttable($task);
406
-				$taskAttachments = mapi_table_queryallrows($taskAttachTable, [PR_ATTACH_NUM]);
407
-				foreach ($taskAttachments as $taskAttach) {
408
-					mapi_message_deleteattach($task, $taskAttach[PR_ATTACH_NUM]);
409
-				}
410
-
411
-				$ignoreProps = [
412
-					$this->props['taskstate'],
413
-					$this->props['taskhistory'],
414
-					$this->props['taskmode'],
415
-					$this->props['taskfcreator'],
416
-				];
417
-				// Ignore PR_ICON_INDEX when task request response
418
-				// is not received item.
419
-				if ($isReceivedItem === false) {
420
-					$ignoreProps[] = PR_ICON_INDEX;
421
-				}
422
-
423
-				// We copy all properties except taskstate, taskhistory, taskmode and taskfcreator properties
424
-				// from $sub message to $task even also we copy all attachments from $sub to $task message.
425
-				mapi_copyto($sub, [], $ignoreProps, $task);
426
-				$senderProps = mapi_getprops($this->message, [
427
-					PR_SENDER_NAME,
428
-					PR_SENDER_EMAIL_ADDRESS,
429
-					PR_SENDER_ENTRYID,
430
-					PR_SENDER_ADDRTYPE,
431
-					PR_SENDER_SEARCH_KEY,
432
-					PR_MESSAGE_DELIVERY_TIME,
433
-					PR_SENT_REPRESENTING_NAME,
434
-					PR_SENT_REPRESENTING_EMAIL_ADDRESS,
435
-					PR_SENT_REPRESENTING_ADDRTYPE,
436
-					PR_SENT_REPRESENTING_ENTRYID,
437
-					PR_SENT_REPRESENTING_SEARCH_KEY, ]);
438
-
439
-				mapi_setprops($task, $senderProps);
440
-
441
-				// Update taskstate and task history (last action done by the assignee)
442
-				mapi_setprops($task, $props);
443
-
444
-				mapi_savechanges($task);
445
-			}
446
-
447
-			mapi_setprops($this->message, $props);
448
-			mapi_savechanges($this->message);
449
-
450
-			if ($isReceivedItem) {
451
-				$this->updateSentTaskRequest();
452
-			}
453
-
454
-			return true;
455
-		}
456
-
457
-		/**
458
-		 * Update the sent task request in sent items folder.
459
-		 *
460
-		 * @return bool
461
-		 */
462
-		public function updateSentTaskRequest() {
463
-			$props = mapi_getprops($this->message, [
464
-				$this->props['taskhistory'],
465
-				$this->props["taskstate"],
466
-				$this->props["ownership"],
467
-				$this->props['task_goid'],
468
-				$this->props['task_acceptance_state'],
469
-				$this->props["tasklastuser"],
470
-				$this->props["tasklastdelegate"], ]);
471
-
472
-			$store = $this->getDefaultStore();
473
-			$storeProps = mapi_getprops($store, [PR_IPM_SENTMAIL_ENTRYID]);
474
-
475
-			$sentFolder = mapi_msgstore_openentry($store, $storeProps[PR_IPM_SENTMAIL_ENTRYID]);
476
-			if (!$sentFolder) {
477
-				return false;
478
-			}
479
-
480
-			// Find the task by looking for the task_goid
481
-			$restriction = [
482
-				RES_PROPERTY, [
483
-					RELOP => RELOP_EQ,
484
-					ULPROPTAG => $this->props['task_goid'],
485
-					VALUE => $props[$this->props['task_goid']],
486
-				],
487
-			];
488
-
489
-			$contentsTable = mapi_folder_getcontentstable($sentFolder);
490
-
491
-			$rows = mapi_table_queryallrows($contentsTable, [PR_ENTRYID], $restriction);
492
-
493
-			if (!empty($rows)) {
494
-				foreach ($rows as $row) {
495
-					$sentTaskRequest = mapi_msgstore_openentry($store, $row[PR_ENTRYID]);
496
-					mapi_setprops($sentTaskRequest, $props);
497
-					mapi_setprops($sentTaskRequest, [PR_PROCESSED => true]);
498
-					mapi_savechanges($sentTaskRequest);
499
-				}
500
-			}
501
-
502
-			return true;
503
-		}
504
-
505
-		/* Create a new message in the current user's outbox and submit it
323
+                if (isset($taskItemProps[$this->props['updatecount']], $props[$this->props['updatecount']])) {
324
+                    if ($props[$this->props['updatecount']] < $taskItemProps[$this->props['updatecount']]) {
325
+                        $result = true;
326
+                    }
327
+                }
328
+            }
329
+
330
+            return $result;
331
+        }
332
+
333
+        // Organizer functions (called by the organizer)
334
+
335
+        /**
336
+         * Processes a task request response, which can be any of the following:
337
+         * - Task accept (task history is marked as accepted)
338
+         * - Task decline (task history is marked as declined)
339
+         * - Task update (updates completion %, etc).
340
+         */
341
+        public function processTaskResponse() {
342
+            $messageProps = mapi_getprops($this->message, [PR_PROCESSED, $this->props["taskupdates"], PR_MESSAGE_TO_ME]);
343
+            if (isset($messageProps[PR_PROCESSED]) && $messageProps[PR_PROCESSED]) {
344
+                return true;
345
+            }
346
+            mapi_setprops($this->message, [PR_PROCESSED => true]);
347
+            mapi_savechanges($this->message);
348
+
349
+            // Get the embedded task information.
350
+            $sub = $this->getEmbeddedTask($this->message);
351
+
352
+            // If task is updated in task folder then we don't need to process
353
+            // old response
354
+            if ($this->isTaskRequestUpdated()) {
355
+                return true;
356
+            }
357
+
358
+            $isReceivedItem = $this->isReceivedItem($messageProps);
359
+
360
+            $isCreateAssociatedTask = false;
361
+            $isAllowUpdateAssociatedTask = $messageProps[$this->props["taskupdates"]];
362
+            $props = mapi_getprops($this->message, [PR_MESSAGE_CLASS]);
363
+            // Set correct taskmode and taskhistory depending on response type
364
+            switch ($props[PR_MESSAGE_CLASS]) {
365
+                case 'IPM.TaskRequest.Accept':
366
+                    $taskHistory = thAccepted;
367
+                    $taskState = $isReceivedItem ? tdsACC : tdsOWN;
368
+                    $taskOwner = $isReceivedItem ? olDelegatedTask : olOwnTask;
369
+                    $taskAcceptanceState = $isReceivedItem ? olTaskDelegationAccepted : olTaskNotDelegated;
370
+
371
+                    break;
372
+
373
+                case 'IPM.TaskRequest.Decline':
374
+                    $isCreateAssociatedTask = $isReceivedItem;
375
+                    $isAllowUpdateAssociatedTask = $isReceivedItem;
376
+                    $taskHistory = thDeclined;
377
+                    $taskState = $isReceivedItem ? tdsDEC : tdsACC;
378
+                    $taskOwner = $isReceivedItem ? olOwnTask : olDelegatedTask;
379
+                    $taskAcceptanceState = $isReceivedItem ? olTaskDelegationDeclined : olTaskDelegationUnknown;
380
+
381
+                    break;
382
+
383
+                case 'IPM.TaskRequest.Update':
384
+                case 'IPM.TaskRequest.Complete':
385
+                    $taskHistory = thUpdated;
386
+                    $taskState = $isReceivedItem ? tdsACC : tdsOWN;
387
+                    $taskAcceptanceState = olTaskNotDelegated;
388
+                    $taskOwner = $isReceivedItem ? olDelegatedTask : olOwnTask;
389
+
390
+                    break;
391
+            }
392
+
393
+            $props = [
394
+                $this->props['taskhistory'] => $taskHistory,
395
+                $this->props['taskstate'] => $taskState,
396
+                $this->props['task_acceptance_state'] => $taskAcceptanceState,
397
+                $this->props['ownership'] => $taskOwner,
398
+            ];
399
+
400
+            // Get the task for this response
401
+            $task = $this->getAssociatedTask($isCreateAssociatedTask);
402
+            if ($task && $isAllowUpdateAssociatedTask) {
403
+                // To avoid duplication of attachments in associated task. we simple remove the
404
+                // all attachments from associated task.
405
+                $taskAttachTable = mapi_message_getattachmenttable($task);
406
+                $taskAttachments = mapi_table_queryallrows($taskAttachTable, [PR_ATTACH_NUM]);
407
+                foreach ($taskAttachments as $taskAttach) {
408
+                    mapi_message_deleteattach($task, $taskAttach[PR_ATTACH_NUM]);
409
+                }
410
+
411
+                $ignoreProps = [
412
+                    $this->props['taskstate'],
413
+                    $this->props['taskhistory'],
414
+                    $this->props['taskmode'],
415
+                    $this->props['taskfcreator'],
416
+                ];
417
+                // Ignore PR_ICON_INDEX when task request response
418
+                // is not received item.
419
+                if ($isReceivedItem === false) {
420
+                    $ignoreProps[] = PR_ICON_INDEX;
421
+                }
422
+
423
+                // We copy all properties except taskstate, taskhistory, taskmode and taskfcreator properties
424
+                // from $sub message to $task even also we copy all attachments from $sub to $task message.
425
+                mapi_copyto($sub, [], $ignoreProps, $task);
426
+                $senderProps = mapi_getprops($this->message, [
427
+                    PR_SENDER_NAME,
428
+                    PR_SENDER_EMAIL_ADDRESS,
429
+                    PR_SENDER_ENTRYID,
430
+                    PR_SENDER_ADDRTYPE,
431
+                    PR_SENDER_SEARCH_KEY,
432
+                    PR_MESSAGE_DELIVERY_TIME,
433
+                    PR_SENT_REPRESENTING_NAME,
434
+                    PR_SENT_REPRESENTING_EMAIL_ADDRESS,
435
+                    PR_SENT_REPRESENTING_ADDRTYPE,
436
+                    PR_SENT_REPRESENTING_ENTRYID,
437
+                    PR_SENT_REPRESENTING_SEARCH_KEY, ]);
438
+
439
+                mapi_setprops($task, $senderProps);
440
+
441
+                // Update taskstate and task history (last action done by the assignee)
442
+                mapi_setprops($task, $props);
443
+
444
+                mapi_savechanges($task);
445
+            }
446
+
447
+            mapi_setprops($this->message, $props);
448
+            mapi_savechanges($this->message);
449
+
450
+            if ($isReceivedItem) {
451
+                $this->updateSentTaskRequest();
452
+            }
453
+
454
+            return true;
455
+        }
456
+
457
+        /**
458
+         * Update the sent task request in sent items folder.
459
+         *
460
+         * @return bool
461
+         */
462
+        public function updateSentTaskRequest() {
463
+            $props = mapi_getprops($this->message, [
464
+                $this->props['taskhistory'],
465
+                $this->props["taskstate"],
466
+                $this->props["ownership"],
467
+                $this->props['task_goid'],
468
+                $this->props['task_acceptance_state'],
469
+                $this->props["tasklastuser"],
470
+                $this->props["tasklastdelegate"], ]);
471
+
472
+            $store = $this->getDefaultStore();
473
+            $storeProps = mapi_getprops($store, [PR_IPM_SENTMAIL_ENTRYID]);
474
+
475
+            $sentFolder = mapi_msgstore_openentry($store, $storeProps[PR_IPM_SENTMAIL_ENTRYID]);
476
+            if (!$sentFolder) {
477
+                return false;
478
+            }
479
+
480
+            // Find the task by looking for the task_goid
481
+            $restriction = [
482
+                RES_PROPERTY, [
483
+                    RELOP => RELOP_EQ,
484
+                    ULPROPTAG => $this->props['task_goid'],
485
+                    VALUE => $props[$this->props['task_goid']],
486
+                ],
487
+            ];
488
+
489
+            $contentsTable = mapi_folder_getcontentstable($sentFolder);
490
+
491
+            $rows = mapi_table_queryallrows($contentsTable, [PR_ENTRYID], $restriction);
492
+
493
+            if (!empty($rows)) {
494
+                foreach ($rows as $row) {
495
+                    $sentTaskRequest = mapi_msgstore_openentry($store, $row[PR_ENTRYID]);
496
+                    mapi_setprops($sentTaskRequest, $props);
497
+                    mapi_setprops($sentTaskRequest, [PR_PROCESSED => true]);
498
+                    mapi_savechanges($sentTaskRequest);
499
+                }
500
+            }
501
+
502
+            return true;
503
+        }
504
+
505
+        /* Create a new message in the current user's outbox and submit it
506 506
 		 *
507 507
 		 * Takes the task passed in the constructor as the task to be sent; recipient should
508 508
 		 * be pre-existing. The task request will be sent to all recipients.
509 509
 		 */
510
-		public function sendTaskRequest($prefix) {
511
-			// Generate a TaskGlobalObjectId
512
-			$taskid = $this->createTGOID();
513
-			$messageprops = mapi_getprops($this->message, [PR_SUBJECT]);
514
-
515
-			// Set properties on Task Request
516
-			mapi_setprops($this->message, [
517
-				$this->props['task_goid'] => $taskid, /* our new task_goid */
518
-				$this->props['taskstate'] => tdsACC,         /* state for our outgoing request */
519
-				$this->props['taskmode'] => tdmtNothing,     /* we're not sending a change */
520
-				$this->props['updatecount'] => 2,            /* version 2 (no idea) */
521
-				$this->props['task_acceptance_state'] => olTaskDelegationUnknown, /* no reply yet */
522
-				$this->props['ownership'] => olDelegatedTask, /* Task has been assigned */
523
-				$this->props['taskhistory'] => thAssigned,    /* Task has been assigned */
524
-				PR_CONVERSATION_TOPIC => $messageprops[PR_SUBJECT],
525
-				PR_ICON_INDEX => ICON_TASK_ASSIGNER,         /* Task request icon */
526
-			]);
527
-			$this->setLastUser();
528
-			$this->setOwnerForAssignor();
529
-			mapi_savechanges($this->message);
530
-
531
-			// Create outgoing task request message
532
-			$outgoing = $this->createOutgoingMessage();
533
-
534
-			// No need to copy PR_ICON_INDEX and  PR_SENT_* information in to outgoing message.
535
-			$ignoreProps = [PR_ICON_INDEX, PR_SENT_REPRESENTING_NAME, PR_SENT_REPRESENTING_EMAIL_ADDRESS, PR_SENT_REPRESENTING_ADDRTYPE, PR_SENT_REPRESENTING_ENTRYID, PR_SENT_REPRESENTING_SEARCH_KEY];
536
-			mapi_copyto($this->message, [], $ignoreProps, $outgoing);
537
-
538
-			// Make it a task request, and put it in sent items after it is sent
539
-			mapi_setprops($outgoing, [
540
-				PR_MESSAGE_CLASS => "IPM.TaskRequest",         /* class is task request */
541
-				$this->props['taskstate'] => tdsOWN,         /* for the recipient he is the task owner */
542
-				$this->props['taskmode'] => tdmtTaskReq,    /* for the recipient it's a request */
543
-				$this->props['updatecount'] => 1,            /* version 2 is in the attachment */
544
-				PR_SUBJECT_PREFIX => $prefix,
545
-				PR_SUBJECT => $prefix . $messageprops[PR_SUBJECT],
546
-			]);
547
-
548
-			$attach = mapi_message_createattach($outgoing);
549
-			mapi_setprops($attach, [
550
-				PR_ATTACH_METHOD => ATTACH_EMBEDDED_MSG,
551
-				PR_ATTACHMENT_HIDDEN => true,
552
-				PR_DISPLAY_NAME => $messageprops[PR_SUBJECT], ]);
553
-
554
-			$sub = mapi_attach_openproperty($attach, PR_ATTACH_DATA_OBJ, IID_IMessage, 0, MAPI_MODIFY | MAPI_CREATE);
555
-
556
-			mapi_copyto($this->message, [], [], $sub);
557
-			mapi_savechanges($sub);
558
-
559
-			mapi_savechanges($attach);
560
-
561
-			mapi_savechanges($outgoing);
562
-			mapi_message_submitmessage($outgoing);
563
-
564
-			return true;
565
-		}
566
-
567
-		// Assignee functions (called by the assignee)
568
-
569
-		/* Update task version counter
510
+        public function sendTaskRequest($prefix) {
511
+            // Generate a TaskGlobalObjectId
512
+            $taskid = $this->createTGOID();
513
+            $messageprops = mapi_getprops($this->message, [PR_SUBJECT]);
514
+
515
+            // Set properties on Task Request
516
+            mapi_setprops($this->message, [
517
+                $this->props['task_goid'] => $taskid, /* our new task_goid */
518
+                $this->props['taskstate'] => tdsACC,         /* state for our outgoing request */
519
+                $this->props['taskmode'] => tdmtNothing,     /* we're not sending a change */
520
+                $this->props['updatecount'] => 2,            /* version 2 (no idea) */
521
+                $this->props['task_acceptance_state'] => olTaskDelegationUnknown, /* no reply yet */
522
+                $this->props['ownership'] => olDelegatedTask, /* Task has been assigned */
523
+                $this->props['taskhistory'] => thAssigned,    /* Task has been assigned */
524
+                PR_CONVERSATION_TOPIC => $messageprops[PR_SUBJECT],
525
+                PR_ICON_INDEX => ICON_TASK_ASSIGNER,         /* Task request icon */
526
+            ]);
527
+            $this->setLastUser();
528
+            $this->setOwnerForAssignor();
529
+            mapi_savechanges($this->message);
530
+
531
+            // Create outgoing task request message
532
+            $outgoing = $this->createOutgoingMessage();
533
+
534
+            // No need to copy PR_ICON_INDEX and  PR_SENT_* information in to outgoing message.
535
+            $ignoreProps = [PR_ICON_INDEX, PR_SENT_REPRESENTING_NAME, PR_SENT_REPRESENTING_EMAIL_ADDRESS, PR_SENT_REPRESENTING_ADDRTYPE, PR_SENT_REPRESENTING_ENTRYID, PR_SENT_REPRESENTING_SEARCH_KEY];
536
+            mapi_copyto($this->message, [], $ignoreProps, $outgoing);
537
+
538
+            // Make it a task request, and put it in sent items after it is sent
539
+            mapi_setprops($outgoing, [
540
+                PR_MESSAGE_CLASS => "IPM.TaskRequest",         /* class is task request */
541
+                $this->props['taskstate'] => tdsOWN,         /* for the recipient he is the task owner */
542
+                $this->props['taskmode'] => tdmtTaskReq,    /* for the recipient it's a request */
543
+                $this->props['updatecount'] => 1,            /* version 2 is in the attachment */
544
+                PR_SUBJECT_PREFIX => $prefix,
545
+                PR_SUBJECT => $prefix . $messageprops[PR_SUBJECT],
546
+            ]);
547
+
548
+            $attach = mapi_message_createattach($outgoing);
549
+            mapi_setprops($attach, [
550
+                PR_ATTACH_METHOD => ATTACH_EMBEDDED_MSG,
551
+                PR_ATTACHMENT_HIDDEN => true,
552
+                PR_DISPLAY_NAME => $messageprops[PR_SUBJECT], ]);
553
+
554
+            $sub = mapi_attach_openproperty($attach, PR_ATTACH_DATA_OBJ, IID_IMessage, 0, MAPI_MODIFY | MAPI_CREATE);
555
+
556
+            mapi_copyto($this->message, [], [], $sub);
557
+            mapi_savechanges($sub);
558
+
559
+            mapi_savechanges($attach);
560
+
561
+            mapi_savechanges($outgoing);
562
+            mapi_message_submitmessage($outgoing);
563
+
564
+            return true;
565
+        }
566
+
567
+        // Assignee functions (called by the assignee)
568
+
569
+        /* Update task version counter
570 570
 		 *
571 571
 		 * Must be called before each update to increase counter
572 572
 		 */
573
-		public function updateTaskRequest() {
574
-			$messageprops = mapi_getprops($this->message, [$this->props['updatecount']]);
573
+        public function updateTaskRequest() {
574
+            $messageprops = mapi_getprops($this->message, [$this->props['updatecount']]);
575 575
 
576
-			if (isset($messageprops)) {
577
-				++$messageprops[$this->props['updatecount']];
578
-			}
579
-			else {
580
-				$messageprops[$this->props['updatecount']] = 1;
581
-			}
576
+            if (isset($messageprops)) {
577
+                ++$messageprops[$this->props['updatecount']];
578
+            }
579
+            else {
580
+                $messageprops[$this->props['updatecount']] = 1;
581
+            }
582 582
 
583
-			mapi_setprops($this->message, $messageprops);
584
-		}
583
+            mapi_setprops($this->message, $messageprops);
584
+        }
585 585
 
586
-		/* Process a task request
586
+        /* Process a task request
587 587
 		 *
588 588
 		 * Message passed should be an IPM.TaskRequest message. The task request is then processed to create
589 589
 		 * the task in the tasks folder if needed.
590 590
 		 */
591
-		public function processTaskRequest() {
592
-			if (!$this->isTaskRequest()) {
593
-				return false;
594
-			}
595
-			$messageProps = mapi_getprops($this->message, [PR_PROCESSED, $this->props["taskupdates"], PR_MESSAGE_TO_ME]);
596
-			if (isset($messageProps[PR_PROCESSED]) && $messageProps[PR_PROCESSED]) {
597
-				return true;
598
-			}
599
-
600
-			// if task is updated in task folder then we don't need to process
601
-			// old request.
602
-			if ($this->isTaskRequestUpdated()) {
603
-				return true;
604
-			}
605
-
606
-			$isReceivedItem = $this->isReceivedItem($messageProps);
607
-
608
-			$props = [];
609
-			$props[PR_PROCESSED] = true;
610
-			$props[$this->props["taskstate"]] = $isReceivedItem ? tdsOWN : tdsACC;
611
-			$props[$this->props["ownership"]] = $isReceivedItem ? olOwnTask : olDelegatedTask;
612
-
613
-			mapi_setprops($this->message, $props);
614
-			mapi_savechanges($this->message);
615
-
616
-			// Don't create associated task in task folder if "taskupdates" is not true.
617
-			if (!$isReceivedItem && !$messageProps[$this->props["taskupdates"]]) {
618
-				return true;
619
-			}
620
-			// create an associated task in task folder while
621
-			// reading/loading task request on client side.
622
-			$task = $this->getAssociatedTask(true);
623
-			$taskProps = mapi_getprops($task, [$this->props['taskmultrecips']]);
624
-			$taskProps[$this->props["taskstate"]] = $isReceivedItem ? tdsOWN : tdsACC;
625
-			$taskProps[$this->props["taskhistory"]] = thAssigned;
626
-			$taskProps[$this->props["taskmode"]] = tdmtNothing;
627
-			$taskProps[$this->props["taskaccepted"]] = false;
628
-			$taskProps[$this->props["taskfcreator"]] = false;
629
-			$taskProps[$this->props["ownership"]] = $isReceivedItem ? olOwnTask : olDelegatedTask;
630
-			$taskProps[$this->props["task_acceptance_state"]] = olTaskNotDelegated;
631
-			$taskProps[PR_ICON_INDEX] = ICON_TASK_ASSIGNEE;
632
-
633
-			mapi_setprops($task, $taskProps);
634
-			$this->setAssignorInRecipients($task);
635
-
636
-			mapi_savechanges($task);
637
-
638
-			return true;
639
-		}
640
-
641
-		/**
642
-		 * Accept a task request and send the response.
643
-		 *
644
-		 * Message passed should be an IPM.Task (eg the task from getAssociatedTask())
645
-		 *
646
-		 * Copies the task to the user's task folder, sets it to accepted, and sends the acceptation
647
-		 * message back to the organizer. The caller is responsible for removing the message.
648
-		 *
649
-		 * @return entryid EntryID of the accepted task
650
-		 */
651
-		public function doAccept() {
652
-			$prefix = _("Task Accepted:") . " ";
653
-			$messageProps = mapi_getprops($this->message, [PR_MESSAGE_CLASS, $this->props['taskstate']]);
654
-
655
-			if (!isset($messageProps[$this->props['taskstate']]) || $messageProps[$this->props['taskstate']] != tdsOWN) {
656
-				// Can only accept assignee task
657
-				return false;
658
-			}
659
-
660
-			$this->setLastUser();
661
-			$this->updateTaskRequest();
662
-
663
-			$props = [
664
-				$this->props['taskhistory'] => thAccepted,
665
-				$this->props['task_assigned_time'] => time(),
666
-				$this->props['taskaccepted'] => true,
667
-				$this->props['task_acceptance_state'] => olTaskNotDelegated, ];
668
-
669
-			// Message is TaskRequest then update the associated task as well.
670
-			if ($this->isTaskRequest($messageProps[PR_MESSAGE_CLASS])) {
671
-				$task = $this->getAssociatedTask(false);
672
-				if ($task) {
673
-					mapi_setprops($task, $props);
674
-					mapi_savechanges($task);
675
-				}
676
-			}
677
-
678
-			// Set as accepted
679
-			mapi_setprops($this->message, $props);
680
-
681
-			// As we copy the all properties from received message we need to remove following
682
-			// properties from accept response.
683
-			mapi_deleteprops($this->message, [PR_MESSAGE_RECIP_ME, PR_MESSAGE_TO_ME, PR_MESSAGE_CC_ME, PR_PROCESSED]);
684
-
685
-			mapi_savechanges($this->message);
686
-
687
-			$this->sendResponse(tdmtTaskAcc, $prefix);
688
-
689
-			return $this->deleteReceivedTR();
690
-		}
691
-
692
-		/* Decline a task request and send the response.
591
+        public function processTaskRequest() {
592
+            if (!$this->isTaskRequest()) {
593
+                return false;
594
+            }
595
+            $messageProps = mapi_getprops($this->message, [PR_PROCESSED, $this->props["taskupdates"], PR_MESSAGE_TO_ME]);
596
+            if (isset($messageProps[PR_PROCESSED]) && $messageProps[PR_PROCESSED]) {
597
+                return true;
598
+            }
599
+
600
+            // if task is updated in task folder then we don't need to process
601
+            // old request.
602
+            if ($this->isTaskRequestUpdated()) {
603
+                return true;
604
+            }
605
+
606
+            $isReceivedItem = $this->isReceivedItem($messageProps);
607
+
608
+            $props = [];
609
+            $props[PR_PROCESSED] = true;
610
+            $props[$this->props["taskstate"]] = $isReceivedItem ? tdsOWN : tdsACC;
611
+            $props[$this->props["ownership"]] = $isReceivedItem ? olOwnTask : olDelegatedTask;
612
+
613
+            mapi_setprops($this->message, $props);
614
+            mapi_savechanges($this->message);
615
+
616
+            // Don't create associated task in task folder if "taskupdates" is not true.
617
+            if (!$isReceivedItem && !$messageProps[$this->props["taskupdates"]]) {
618
+                return true;
619
+            }
620
+            // create an associated task in task folder while
621
+            // reading/loading task request on client side.
622
+            $task = $this->getAssociatedTask(true);
623
+            $taskProps = mapi_getprops($task, [$this->props['taskmultrecips']]);
624
+            $taskProps[$this->props["taskstate"]] = $isReceivedItem ? tdsOWN : tdsACC;
625
+            $taskProps[$this->props["taskhistory"]] = thAssigned;
626
+            $taskProps[$this->props["taskmode"]] = tdmtNothing;
627
+            $taskProps[$this->props["taskaccepted"]] = false;
628
+            $taskProps[$this->props["taskfcreator"]] = false;
629
+            $taskProps[$this->props["ownership"]] = $isReceivedItem ? olOwnTask : olDelegatedTask;
630
+            $taskProps[$this->props["task_acceptance_state"]] = olTaskNotDelegated;
631
+            $taskProps[PR_ICON_INDEX] = ICON_TASK_ASSIGNEE;
632
+
633
+            mapi_setprops($task, $taskProps);
634
+            $this->setAssignorInRecipients($task);
635
+
636
+            mapi_savechanges($task);
637
+
638
+            return true;
639
+        }
640
+
641
+        /**
642
+         * Accept a task request and send the response.
643
+         *
644
+         * Message passed should be an IPM.Task (eg the task from getAssociatedTask())
645
+         *
646
+         * Copies the task to the user's task folder, sets it to accepted, and sends the acceptation
647
+         * message back to the organizer. The caller is responsible for removing the message.
648
+         *
649
+         * @return entryid EntryID of the accepted task
650
+         */
651
+        public function doAccept() {
652
+            $prefix = _("Task Accepted:") . " ";
653
+            $messageProps = mapi_getprops($this->message, [PR_MESSAGE_CLASS, $this->props['taskstate']]);
654
+
655
+            if (!isset($messageProps[$this->props['taskstate']]) || $messageProps[$this->props['taskstate']] != tdsOWN) {
656
+                // Can only accept assignee task
657
+                return false;
658
+            }
659
+
660
+            $this->setLastUser();
661
+            $this->updateTaskRequest();
662
+
663
+            $props = [
664
+                $this->props['taskhistory'] => thAccepted,
665
+                $this->props['task_assigned_time'] => time(),
666
+                $this->props['taskaccepted'] => true,
667
+                $this->props['task_acceptance_state'] => olTaskNotDelegated, ];
668
+
669
+            // Message is TaskRequest then update the associated task as well.
670
+            if ($this->isTaskRequest($messageProps[PR_MESSAGE_CLASS])) {
671
+                $task = $this->getAssociatedTask(false);
672
+                if ($task) {
673
+                    mapi_setprops($task, $props);
674
+                    mapi_savechanges($task);
675
+                }
676
+            }
677
+
678
+            // Set as accepted
679
+            mapi_setprops($this->message, $props);
680
+
681
+            // As we copy the all properties from received message we need to remove following
682
+            // properties from accept response.
683
+            mapi_deleteprops($this->message, [PR_MESSAGE_RECIP_ME, PR_MESSAGE_TO_ME, PR_MESSAGE_CC_ME, PR_PROCESSED]);
684
+
685
+            mapi_savechanges($this->message);
686
+
687
+            $this->sendResponse(tdmtTaskAcc, $prefix);
688
+
689
+            return $this->deleteReceivedTR();
690
+        }
691
+
692
+        /* Decline a task request and send the response.
693 693
 		 *
694 694
 		 * Passed message must be a task request message, ie isTaskRequest() must return TRUE.
695 695
 		 *
@@ -697,591 +697,591 @@  discard block
 block discarded – undo
697 697
 		 *
698 698
 		 * @return boolean TRUE on success, FALSE on failure
699 699
 		 */
700
-		public function doDecline() {
701
-			$prefix = _("Task Declined:") . " ";
702
-			$messageProps = mapi_getprops($this->message, [$this->props['taskstate']]);
703
-
704
-			if (!isset($messageProps[$this->props['taskstate']]) || $messageProps[$this->props['taskstate']] != tdsOWN) {
705
-				return false; // Can only decline assignee task
706
-			}
707
-
708
-			$this->setLastUser();
709
-			$this->updateTaskRequest();
710
-
711
-			// Set as declined
712
-			mapi_setprops($this->message, [
713
-				$this->props['taskhistory'] => thDeclined,
714
-				$this->props['task_acceptance_state'] => olTaskDelegationDeclined,
715
-			]);
716
-			mapi_deleteprops($this->message, [PR_MESSAGE_RECIP_ME, PR_MESSAGE_TO_ME, PR_MESSAGE_CC_ME, PR_PROCESSED]);
717
-			mapi_savechanges($this->message);
718
-
719
-			$this->sendResponse(tdmtTaskDec, $prefix);
720
-
721
-			// Delete the associated task when task request is declined by the assignee.
722
-			$task = $this->getAssociatedTask(false);
723
-			if ($task) {
724
-				$taskFolder = $this->getDefaultTasksFolder();
725
-				$props = mapi_getprops($task, [PR_ENTRYID]);
726
-				mapi_folder_deletemessages($taskFolder, [$props[PR_ENTRYID]]);
727
-			}
728
-
729
-			return $this->deleteReceivedTR();
730
-		}
731
-
732
-		/**
733
-		 * Send an update of the task if requested, and send the Status-On-Completion report if complete and requested.
734
-		 *
735
-		 * If no updates were requested from the organizer, this function does nothing.
736
-		 *
737
-		 * @return bool TRUE if the update succeeded, FALSE otherwise
738
-		 */
739
-		public function doUpdate() {
740
-			$messageProps = mapi_getprops($this->message, [$this->props['taskstate'], PR_SUBJECT]);
741
-
742
-			if (!isset($messageProps[$this->props['taskstate']]) || $messageProps[$this->props['taskstate']] != tdsOWN) {
743
-				return false; // Can only update assignee task
744
-			}
745
-
746
-			$this->setLastUser();
747
-			$this->updateTaskRequest();
748
-
749
-			// Set as updated
750
-			mapi_setprops($this->message, [$this->props['taskhistory'] => thUpdated]);
751
-
752
-			mapi_savechanges($this->message);
753
-
754
-			$props = mapi_getprops($this->message, [$this->props['taskupdates'], $this->props['tasksoc'], $this->props['recurring'], $this->props['complete']]);
755
-			if (!$props[$this->props['complete']] && $props[$this->props['taskupdates']] && !(isset($props[$this->props['recurring']]) && $props[$this->props['recurring']])) {
756
-				$this->sendResponse(tdmtTaskUpd, _("Task Updated:") . " ");
757
-			}
758
-			elseif ($props[$this->props['complete']]) {
759
-				$this->sendResponse(tdmtTaskUpd, _("Task Completed:") . " ");
760
-			}
761
-
762
-			return true;
763
-		}
764
-
765
-		/**
766
-		 * Get the store associated with the task.
767
-		 *
768
-		 * Normally this will just open the store that the processed message is in. However, if the message is opened
769
-		 * by a delegate, this function opens the store that the message was delegated from.
770
-		 */
771
-		public function getTaskFolderStore() {
772
-			$ownerentryid = false;
773
-
774
-			$rcvdprops = mapi_getprops($this->message, [PR_RCVD_REPRESENTING_ENTRYID]);
775
-			if (isset($rcvdprops[PR_RCVD_REPRESENTING_ENTRYID])) {
776
-				$ownerentryid = $rcvdprops;
777
-			}
778
-
779
-			if (!$ownerentryid) {
780
-				$store = $this->store;
781
-			}
782
-			else {
783
-				$ab = mapi_openaddressbook($this->session);
784
-				if (!$ab) {
785
-					return false;
786
-				}
787
-
788
-				$mailuser = mapi_ab_openentry($ab, $ownerentryid);
789
-				if (!$mailuser) {
790
-					return false;
791
-				}
792
-
793
-				$mailuserprops = mapi_getprops($mailuser, [PR_EMAIL_ADDRESS]);
794
-				if (!isset($mailuserprops[PR_EMAIL_ADDRESS])) {
795
-					return false;
796
-				}
797
-
798
-				$storeid = mapi_msgstore_createentryid($this->store, $mailuserprops[PR_EMAIL_ADDRESS]);
799
-
800
-				$store = mapi_openmsgstore($this->session, $storeid);
801
-			}
802
-
803
-			return $store;
804
-		}
805
-
806
-		/**
807
-		 * Open the default task folder for the current user, or the specified user if passed.
808
-		 */
809
-		public function getDefaultTasksFolder() {
810
-			$store = $this->getTaskFolderStore();
811
-
812
-			$inbox = mapi_msgstore_getreceivefolder($store);
813
-			$inboxprops = mapi_getprops($inbox, [PR_IPM_TASK_ENTRYID]);
814
-			if (!isset($inboxprops[PR_IPM_TASK_ENTRYID])) {
815
-				return false;
816
-			}
817
-
818
-			return mapi_msgstore_openentry($store, $inboxprops[PR_IPM_TASK_ENTRYID]);
819
-		}
820
-
821
-		/**
822
-		 * Function prepare the sent representing properties from given MAPI store.
823
-		 *
824
-		 * @param $store MAPI store object
825
-		 *
826
-		 * @return array|bool if store is not mail box owner entryid then
827
-		 *                    return false else prepare the sent representing props and return it
828
-		 */
829
-		public function getSentReprProps($store) {
830
-			$storeprops = mapi_getprops($store, [PR_MAILBOX_OWNER_ENTRYID]);
831
-			if (!isset($storeprops[PR_MAILBOX_OWNER_ENTRYID])) {
832
-				return false;
833
-			}
834
-
835
-			$ab = mapi_openaddressbook($this->session);
836
-			$mailuser = mapi_ab_openentry($ab, $storeprops[PR_MAILBOX_OWNER_ENTRYID]);
837
-			$mailuserprops = mapi_getprops($mailuser, [PR_ADDRTYPE, PR_EMAIL_ADDRESS, PR_DISPLAY_NAME, PR_SEARCH_KEY, PR_ENTRYID]);
838
-
839
-			$props = [];
840
-			$props[PR_SENT_REPRESENTING_ADDRTYPE] = $mailuserprops[PR_ADDRTYPE];
841
-			$props[PR_SENT_REPRESENTING_EMAIL_ADDRESS] = $mailuserprops[PR_EMAIL_ADDRESS];
842
-			$props[PR_SENT_REPRESENTING_NAME] = $mailuserprops[PR_DISPLAY_NAME];
843
-			$props[PR_SENT_REPRESENTING_SEARCH_KEY] = $mailuserprops[PR_SEARCH_KEY];
844
-			$props[PR_SENT_REPRESENTING_ENTRYID] = $mailuserprops[PR_ENTRYID];
845
-
846
-			return $props;
847
-		}
848
-
849
-		/**
850
-		 * Creates an outgoing message based on the passed message - will set delegate information
851
-		 * and sent mail folder.
852
-		 */
853
-		public function createOutgoingMessage() {
854
-			// Open our default store for this user (that's the only store we can submit in)
855
-			$store = $this->getDefaultStore();
856
-			$storeprops = mapi_getprops($store, [PR_IPM_OUTBOX_ENTRYID, PR_IPM_SENTMAIL_ENTRYID]);
857
-
858
-			$outbox = mapi_msgstore_openentry($store, $storeprops[PR_IPM_OUTBOX_ENTRYID]);
859
-			if (!$outbox) {
860
-				return false;
861
-			}
862
-
863
-			$outgoing = mapi_folder_createmessage($outbox);
864
-			if (!$outgoing) {
865
-				return false;
866
-			}
867
-
868
-			// Set SENT_REPRESENTING in case we're sending as a delegate
869
-			$ownerstore = $this->getTaskFolderStore();
870
-			$sentreprprops = $this->getSentReprProps($ownerstore);
871
-			mapi_setprops($outgoing, $sentreprprops);
872
-
873
-			mapi_setprops($outgoing, [PR_SENTMAIL_ENTRYID => $storeprops[PR_IPM_SENTMAIL_ENTRYID]]);
874
-
875
-			return $outgoing;
876
-		}
877
-
878
-		/**
879
-		 * Send a response message (from assignee back to organizer).
880
-		 *
881
-		 * @param $type int Type of response (tdmtTaskAcc, tdmtTaskDec, tdmtTaskUpd);
882
-		 * @param mixed $prefix
883
-		 *
884
-		 * @return bool TRUE on success
885
-		 */
886
-		public function sendResponse($type, $prefix) {
887
-			// Create a message in our outbox
888
-			$outgoing = $this->createOutgoingMessage();
889
-			$messageprops = mapi_getprops($this->message, [PR_CONVERSATION_TOPIC, PR_MESSAGE_CLASS, $this->props['complete']]);
890
-
891
-			$attach = mapi_message_createattach($outgoing);
892
-			mapi_setprops($attach, [PR_ATTACH_METHOD => ATTACH_EMBEDDED_MSG, PR_DISPLAY_NAME => $messageprops[PR_CONVERSATION_TOPIC], PR_ATTACHMENT_HIDDEN => true]);
893
-			$sub = mapi_attach_openproperty($attach, PR_ATTACH_DATA_OBJ, IID_IMessage, 0, MAPI_CREATE | MAPI_MODIFY);
894
-
895
-			$message = !$this->isTaskRequest() ? $this->message : $this->getAssociatedTask(false);
896
-
897
-			$ignoreProps = [PR_ICON_INDEX, $this->props["categories"], PR_SENT_REPRESENTING_NAME, PR_SENT_REPRESENTING_EMAIL_ADDRESS, PR_SENT_REPRESENTING_ADDRTYPE, PR_SENT_REPRESENTING_ENTRYID, PR_SENT_REPRESENTING_SEARCH_KEY];
898
-
899
-			mapi_copyto($message, [], $ignoreProps, $outgoing);
900
-			mapi_copyto($message, [], [], $sub);
901
-
902
-			if (!$this->setRecipientsForResponse($outgoing, $type)) {
903
-				return false;
904
-			}
905
-
906
-			$props = [];
907
-
908
-			switch ($type) {
909
-				case tdmtTaskAcc:
910
-					$props[PR_MESSAGE_CLASS] = "IPM.TaskRequest.Accept";
911
-					mapi_setprops($sub, [PR_ICON_INDEX => ICON_TASK_ASSIGNER]);
912
-
913
-					break;
914
-
915
-				case tdmtTaskDec:
916
-					$props[PR_MESSAGE_CLASS] = "IPM.TaskRequest.Decline";
917
-					mapi_setprops($sub, [PR_ICON_INDEX => ICON_TASK_DECLINE]);
918
-
919
-					break;
920
-
921
-				case tdmtTaskUpd:
922
-					mapi_setprops($sub, [PR_ICON_INDEX => ICON_TASK_ASSIGNER]);
923
-					if ($messageprops[$this->props['complete']]) {
924
-						$props[PR_MESSAGE_CLASS] = "IPM.TaskRequest.Complete";
925
-					}
926
-					else {
927
-						$props[PR_MESSAGE_CLASS] = "IPM.TaskRequest.Update";
928
-					}
929
-
930
-					break;
931
-			}
932
-
933
-			mapi_savechanges($sub);
934
-			mapi_savechanges($attach);
935
-
936
-			$props[PR_SUBJECT] = $prefix . $messageprops[PR_CONVERSATION_TOPIC];
937
-			$props[$this->props['taskmode']] = $type;
938
-			$props[$this->props['task_assigned_time']] = time();
939
-
940
-			mapi_setprops($outgoing, $props);
941
-
942
-			// taskCommentsInfo contains some comments which added by assignee while
943
-			// edit response before sending task response.
944
-			if ($this->taskCommentsInfo) {
945
-				$comments = $this->getTaskCommentsInfo();
946
-				$stream = mapi_openproperty($outgoing, PR_BODY, IID_IStream, STGM_TRANSACTED, MAPI_CREATE | MAPI_MODIFY);
947
-				mapi_stream_setsize($stream, strlen($comments));
948
-				mapi_stream_write($stream, $comments);
949
-				mapi_stream_commit($stream);
950
-			}
951
-
952
-			mapi_savechanges($outgoing);
953
-			mapi_message_submitmessage($outgoing);
954
-
955
-			return true;
956
-		}
957
-
958
-		public function getDefaultStore() {
959
-			$table = mapi_getmsgstorestable($this->session);
960
-			$rows = mapi_table_queryallrows($table, [PR_DEFAULT_STORE, PR_ENTRYID]);
961
-
962
-			foreach ($rows as $row) {
963
-				if ($row[PR_DEFAULT_STORE]) {
964
-					return mapi_openmsgstore($this->session, $row[PR_ENTRYID]);
965
-				}
966
-			}
967
-
968
-			return false;
969
-		}
970
-
971
-		/**
972
-		 * Creates a new TaskGlobalObjId.
973
-		 *
974
-		 * Just 16 bytes of random data
975
-		 */
976
-		public function createTGOID() {
977
-			$goid = "";
978
-			for ($i = 0; $i < 16; ++$i) {
979
-				$goid .= chr(rand(0, 255));
980
-			}
981
-
982
-			return $goid;
983
-		}
984
-
985
-		/**
986
-		 * Function used to get the embedded task of task request. Which further used to
987
-		 * Create/Update associated task of assigner/assignee.
988
-		 *
989
-		 * @param object $message which contains embedded task
990
-		 *
991
-		 * @return false|object $task if found embedded task else false
992
-		 */
993
-		public function getEmbeddedTask($message) {
994
-			$task = false;
995
-			$goid = mapi_getprops($message, [$this->props["task_goid"]]);
996
-			$attachmentTable = mapi_message_getattachmenttable($message);
997
-			$restriction = [
998
-				RES_PROPERTY,
999
-				[
1000
-					RELOP => RELOP_EQ,
1001
-					ULPROPTAG => PR_ATTACH_METHOD,
1002
-					VALUE => ATTACH_EMBEDDED_MSG, ],
1003
-			];
1004
-			$rows = mapi_table_queryallrows($attachmentTable, [PR_ATTACH_NUM], $restriction);
1005
-
1006
-			if (empty($rows)) {
1007
-				return $task;
1008
-			}
1009
-
1010
-			foreach ($rows as $row) {
1011
-				try {
1012
-					$attach = mapi_message_openattach($message, $row[PR_ATTACH_NUM]);
1013
-					$task = mapi_attach_openobj($attach);
1014
-				}
1015
-				catch (MAPIException $e) {
1016
-					continue;
1017
-				}
1018
-
1019
-				$taskGoid = mapi_getprops($task, [$this->props["task_goid"]]);
1020
-				if ($goid[$this->props["task_goid"]] === $taskGoid[$this->props["task_goid"]]) {
1021
-					mapi_setprops($attach, [PR_ATTACHMENT_HIDDEN => true]);
1022
-					mapi_savechanges($attach);
1023
-					mapi_savechanges($message);
1024
-
1025
-					break;
1026
-				}
1027
-			}
1028
-
1029
-			return $task;
1030
-		}
1031
-
1032
-		/**
1033
-		 * Function was used to set the user name who has last used this task also it was
1034
-		 * update the  tasklastdelegate and task_assigned_time.
1035
-		 */
1036
-		public function setLastUser() {
1037
-			$delegatestore = $this->getDefaultStore();
1038
-			$taskstore = $this->getTaskFolderStore();
1039
-
1040
-			$delegateprops = mapi_getprops($delegatestore, [PR_MAILBOX_OWNER_NAME]);
1041
-			$taskprops = mapi_getprops($taskstore, [PR_MAILBOX_OWNER_NAME]);
1042
-
1043
-			// The owner of the task
1044
-			$username = $delegateprops[PR_MAILBOX_OWNER_NAME];
1045
-			// This is me (the one calling the script)
1046
-			$delegate = $taskprops[PR_MAILBOX_OWNER_NAME];
1047
-
1048
-			if ($this->isTaskRequest()) {
1049
-				$task = $this->getAssociatedTask(false);
1050
-				mapi_setprops($task, [$this->props["tasklastuser"] => $username, $this->props["tasklastdelegate"] => $delegate, $this->props['task_assigned_time'] => time()]);
1051
-				mapi_savechanges($task);
1052
-			}
1053
-			mapi_setprops($this->message, [$this->props["tasklastuser"] => $username, $this->props["tasklastdelegate"] => $delegate, $this->props['task_assigned_time'] => time()]);
1054
-		}
1055
-
1056
-		/**
1057
-		 * Assignee becomes the owner when a user/assignor assigns any task to someone. Also there can be more than one assignee.
1058
-		 * This function sets assignee as owner in the assignor's copy of task.
1059
-		 */
1060
-		public function setOwnerForAssignor() {
1061
-			$recipTable = mapi_message_getrecipienttable($this->message);
1062
-			$recips = mapi_table_queryallrows($recipTable, [PR_DISPLAY_NAME]);
1063
-
1064
-			if (!empty($recips)) {
1065
-				$owner = [];
1066
-				foreach ($recips as $value) {
1067
-					$owner[] = $value[PR_DISPLAY_NAME];
1068
-				}
1069
-
1070
-				$props = [$this->props['owner'] => implode("; ", $owner)];
1071
-				mapi_setprops($this->message, $props);
1072
-			}
1073
-		}
1074
-
1075
-		/**
1076
-		 * Sets assignor as recipients in assignee's copy of task.
1077
-		 *
1078
-		 * If assignor has requested task updates then the assignor is added as recipient type MAPI_CC.
1079
-		 *
1080
-		 * Also if assignor has request SOC then the assignor is also add as recipient type MAPI_BCC
1081
-		 *
1082
-		 * @param $task message MAPI message which assignee's copy of task
1083
-		 */
1084
-		public function setAssignorInRecipients($task) {
1085
-			$recipTable = mapi_message_getrecipienttable($task);
1086
-
1087
-			// Delete all MAPI_TO recipients
1088
-			$recips = mapi_table_queryallrows($recipTable, [PR_ROWID], [
1089
-				RES_PROPERTY,
1090
-				[
1091
-					RELOP => RELOP_EQ,
1092
-					ULPROPTAG => PR_RECIPIENT_TYPE,
1093
-					VALUE => MAPI_TO,
1094
-				], ]);
1095
-			foreach ($recips as $recip) {
1096
-				mapi_message_modifyrecipients($task, MODRECIP_REMOVE, [$recip]);
1097
-			}
1098
-
1099
-			$recips = [];
1100
-			$taskReqProps = mapi_getprops($this->message, [PR_SENT_REPRESENTING_NAME, PR_SENT_REPRESENTING_EMAIL_ADDRESS, PR_SENT_REPRESENTING_ENTRYID, PR_SENT_REPRESENTING_ADDRTYPE, PR_SENT_REPRESENTING_SEARCH_KEY]);
1101
-			$associatedTaskProps = mapi_getprops($task, [$this->props['taskupdates'], $this->props['tasksoc'], $this->props['taskmultrecips']]);
1102
-
1103
-			// Build assignor info
1104
-			$assignor = [
1105
-				PR_ENTRYID => $taskReqProps[PR_SENT_REPRESENTING_ENTRYID],
1106
-				PR_DISPLAY_NAME => $taskReqProps[PR_SENT_REPRESENTING_NAME],
1107
-				PR_EMAIL_ADDRESS => $taskReqProps[PR_SENT_REPRESENTING_EMAIL_ADDRESS],
1108
-				PR_RECIPIENT_DISPLAY_NAME => $taskReqProps[PR_SENT_REPRESENTING_NAME],
1109
-				PR_ADDRTYPE => empty($taskReqProps[PR_SENT_REPRESENTING_ADDRTYPE]) ? 'SMTP' : $taskReqProps[PR_SENT_REPRESENTING_ADDRTYPE],
1110
-				PR_RECIPIENT_FLAGS => recipSendable,
1111
-				PR_SEARCH_KEY => $taskReqProps[PR_SENT_REPRESENTING_SEARCH_KEY],
1112
-			];
1113
-
1114
-			// Assignor has requested task updates, so set him/her as MAPI_CC in recipienttable.
1115
-			if ((isset($associatedTaskProps[$this->props['taskupdates']]) && $associatedTaskProps[$this->props['taskupdates']]) &&
1116
-				!(isset($associatedTaskProps[$this->props['taskmultrecips']]) && $associatedTaskProps[$this->props['taskmultrecips']] == tmrReceived)) {
1117
-				$assignor[PR_RECIPIENT_TYPE] = MAPI_CC;
1118
-				$recips[] = $assignor;
1119
-			}
1120
-
1121
-			// Assignor wants to receive an email report when task is mark as 'Complete', so in recipients as MAPI_BCC
1122
-			if ($associatedTaskProps[$this->props['tasksoc']]) {
1123
-				$assignor[PR_RECIPIENT_TYPE] = MAPI_BCC;
1124
-				$recips[] = $assignor;
1125
-			}
1126
-
1127
-			if (!empty($recips)) {
1128
-				mapi_message_modifyrecipients($task, MODRECIP_ADD, $recips);
1129
-			}
1130
-		}
1131
-
1132
-		/**
1133
-		 * Deletes incoming task request from Inbox.
1134
-		 *
1135
-		 * @returns array returns PR_ENTRYID, PR_STORE_ENTRYID and PR_PARENT_ENTRYID of the deleted task request
1136
-		 */
1137
-		public function deleteReceivedTR() {
1138
-			$store = $this->getTaskFolderStore();
1139
-			$storeType = mapi_getprops($store, [PR_MDB_PROVIDER]);
1140
-			if ($storeType[PR_MDB_PROVIDER] === ZARAFA_STORE_PUBLIC_GUID) {
1141
-				$store = $this->getDefaultStore();
1142
-			}
1143
-			$inbox = mapi_msgstore_getreceivefolder($store);
1144
-
1145
-			$storeProps = mapi_getprops($store, [PR_IPM_WASTEBASKET_ENTRYID]);
1146
-			$props = mapi_getprops($this->message, [$this->props['task_goid']]);
1147
-			$goid = $props[$this->props['task_goid']];
1148
-
1149
-			// Find the task by looking for the task_goid
1150
-			$restriction = [
1151
-				RES_PROPERTY,
1152
-				[
1153
-					RELOP => RELOP_EQ,
1154
-					ULPROPTAG => $this->props['task_goid'],
1155
-					VALUE => $goid, ],
1156
-			];
1157
-
1158
-			$contents = mapi_folder_getcontentstable($inbox);
1159
-
1160
-			$rows = mapi_table_queryallrows($contents, [PR_ENTRYID, PR_PARENT_ENTRYID, PR_STORE_ENTRYID], $restriction);
1161
-
1162
-			if (!empty($rows)) {
1163
-				// If there are multiple, just use the first
1164
-				$entryid = $rows[0][PR_ENTRYID];
1165
-				$wastebasket = mapi_msgstore_openentry($store, $storeProps[PR_IPM_WASTEBASKET_ENTRYID]);
1166
-				mapi_folder_copymessages($inbox, [$entryid], $wastebasket, MESSAGE_MOVE);
1167
-
1168
-				return [PR_ENTRYID => $entryid, PR_PARENT_ENTRYID => $rows[0][PR_PARENT_ENTRYID], PR_STORE_ENTRYID => $rows[0][PR_STORE_ENTRYID]];
1169
-			}
1170
-
1171
-			return false;
1172
-		}
1173
-
1174
-		/**
1175
-		 * Sets recipients for the outgoing message according to type of the response.
1176
-		 *
1177
-		 * If it is a task update, then only recipient type MAPI_CC are taken from the task message.
1178
-		 *
1179
-		 * If it is accept/decline response, then PR_SENT_REPRESENTATING_XXXX are taken as recipient.
1180
-		 *
1181
-		 *@param $outgoing MAPI_message outgoing mapi message
1182
-		 *@param $responseType String response type
1183
-		 */
1184
-		public function setRecipientsForResponse($outgoing, $responseType) {
1185
-			// Clear recipients from outgoing msg
1186
-			$this->deleteAllRecipients($outgoing);
1187
-
1188
-			// If it is a task update then get MAPI_CC recipients which are assignors who has asked for task update.
1189
-			if ($responseType == tdmtTaskUpd) {
1190
-				$props = mapi_getprops($this->message, [$this->props['complete']]);
1191
-				$isComplete = $props[$this->props['complete']];
1192
-
1193
-				$recipTable = mapi_message_getrecipienttable($this->message);
1194
-				$recips = mapi_table_queryallrows($recipTable, $this->recipProps, [
1195
-					RES_PROPERTY,
1196
-					[
1197
-						RELOP => RELOP_EQ,
1198
-						ULPROPTAG => PR_RECIPIENT_TYPE,
1199
-						VALUE => ($isComplete ? MAPI_BCC : MAPI_CC),
1200
-					],
1201
-				]);
1202
-
1203
-				// No recipients found, return error
1204
-				if (empty($recips)) {
1205
-					return false;
1206
-				}
1207
-
1208
-				foreach ($recips as $recip) {
1209
-					$recip[PR_RECIPIENT_TYPE] = MAPI_TO;    // Change recipient type to MAPI_TO
1210
-					mapi_message_modifyrecipients($outgoing, MODRECIP_ADD, [$recip]);
1211
-				}
1212
-
1213
-				return true;
1214
-			}
1215
-
1216
-			$orgprops = mapi_getprops($this->message, [PR_SENT_REPRESENTING_NAME, PR_SENT_REPRESENTING_EMAIL_ADDRESS, PR_SENT_REPRESENTING_ADDRTYPE, PR_SENT_REPRESENTING_ENTRYID, PR_SUBJECT]);
1217
-			$recip = [
1218
-				PR_DISPLAY_NAME => $orgprops[PR_SENT_REPRESENTING_NAME],
1219
-				PR_EMAIL_ADDRESS => $orgprops[PR_SENT_REPRESENTING_EMAIL_ADDRESS],
1220
-				PR_ADDRTYPE => $orgprops[PR_SENT_REPRESENTING_ADDRTYPE],
1221
-				PR_ENTRYID => $orgprops[PR_SENT_REPRESENTING_ENTRYID],
1222
-				PR_RECIPIENT_TYPE => MAPI_TO, ];
1223
-
1224
-			mapi_message_modifyrecipients($outgoing, MODRECIP_ADD, [$recip]);
1225
-
1226
-			return true;
1227
-		}
1228
-
1229
-		/**
1230
-		 * Deletes all recipients from given message object.
1231
-		 *
1232
-		 * @param $message MAPI message from which recipients are to be removed
1233
-		 */
1234
-		public function deleteAllRecipients($message) {
1235
-			$recipTable = mapi_message_getrecipienttable($message);
1236
-			$recipRows = mapi_table_queryallrows($recipTable, [PR_ROWID]);
1237
-
1238
-			foreach ($recipRows as $recipient) {
1239
-				mapi_message_modifyrecipients($message, MODRECIP_REMOVE, [$recipient]);
1240
-			}
1241
-		}
1242
-
1243
-		/**
1244
-		 * Function used to mark the record to complete and send complete update
1245
-		 * notification to assigner.
1246
-		 *
1247
-		 * @return bool TRUE if the update succeeded, FALSE otherwise
1248
-		 */
1249
-		public function sendCompleteUpdate() {
1250
-			$messageprops = mapi_getprops($this->message, [$this->props['taskstate']]);
1251
-
1252
-			if (!isset($messageprops[$this->props['taskstate']]) || $messageprops[$this->props['taskstate']] != tdsOWN) {
1253
-				return false; // Can only decline assignee task
1254
-			}
1255
-
1256
-			mapi_setprops(
1257
-				$this->message,
1258
-				[
1259
-					$this->props['complete'] => true,
1260
-					$this->props['datecompleted'] => time(),
1261
-					$this->props['status'] => 2,
1262
-					$this->props['percent_complete'] => 1, ]
1263
-			);
1264
-
1265
-			return $this->doUpdate();
1266
-		}
1267
-
1268
-		/**
1269
-		 * Function returns extra info about task request comments along with message body
1270
-		 * which will be included in body while sending task request/response.
1271
-		 *
1272
-		 * @return string info about task request comments along with message body
1273
-		 */
1274
-		public function getTaskCommentsInfo() {
1275
-			return $this->taskCommentsInfo;
1276
-		}
1277
-
1278
-		/**
1279
-		 * Function sets extra info about task request comments along with message body
1280
-		 * which will be included in body while sending task request/response.
1281
-		 *
1282
-		 * @param string $taskCommentsInfo info about task request comments along with message body
1283
-		 */
1284
-		public function setTaskCommentsInfo($taskCommentsInfo) {
1285
-			$this->taskCommentsInfo = $taskCommentsInfo;
1286
-		}
1287
-	}
700
+        public function doDecline() {
701
+            $prefix = _("Task Declined:") . " ";
702
+            $messageProps = mapi_getprops($this->message, [$this->props['taskstate']]);
703
+
704
+            if (!isset($messageProps[$this->props['taskstate']]) || $messageProps[$this->props['taskstate']] != tdsOWN) {
705
+                return false; // Can only decline assignee task
706
+            }
707
+
708
+            $this->setLastUser();
709
+            $this->updateTaskRequest();
710
+
711
+            // Set as declined
712
+            mapi_setprops($this->message, [
713
+                $this->props['taskhistory'] => thDeclined,
714
+                $this->props['task_acceptance_state'] => olTaskDelegationDeclined,
715
+            ]);
716
+            mapi_deleteprops($this->message, [PR_MESSAGE_RECIP_ME, PR_MESSAGE_TO_ME, PR_MESSAGE_CC_ME, PR_PROCESSED]);
717
+            mapi_savechanges($this->message);
718
+
719
+            $this->sendResponse(tdmtTaskDec, $prefix);
720
+
721
+            // Delete the associated task when task request is declined by the assignee.
722
+            $task = $this->getAssociatedTask(false);
723
+            if ($task) {
724
+                $taskFolder = $this->getDefaultTasksFolder();
725
+                $props = mapi_getprops($task, [PR_ENTRYID]);
726
+                mapi_folder_deletemessages($taskFolder, [$props[PR_ENTRYID]]);
727
+            }
728
+
729
+            return $this->deleteReceivedTR();
730
+        }
731
+
732
+        /**
733
+         * Send an update of the task if requested, and send the Status-On-Completion report if complete and requested.
734
+         *
735
+         * If no updates were requested from the organizer, this function does nothing.
736
+         *
737
+         * @return bool TRUE if the update succeeded, FALSE otherwise
738
+         */
739
+        public function doUpdate() {
740
+            $messageProps = mapi_getprops($this->message, [$this->props['taskstate'], PR_SUBJECT]);
741
+
742
+            if (!isset($messageProps[$this->props['taskstate']]) || $messageProps[$this->props['taskstate']] != tdsOWN) {
743
+                return false; // Can only update assignee task
744
+            }
745
+
746
+            $this->setLastUser();
747
+            $this->updateTaskRequest();
748
+
749
+            // Set as updated
750
+            mapi_setprops($this->message, [$this->props['taskhistory'] => thUpdated]);
751
+
752
+            mapi_savechanges($this->message);
753
+
754
+            $props = mapi_getprops($this->message, [$this->props['taskupdates'], $this->props['tasksoc'], $this->props['recurring'], $this->props['complete']]);
755
+            if (!$props[$this->props['complete']] && $props[$this->props['taskupdates']] && !(isset($props[$this->props['recurring']]) && $props[$this->props['recurring']])) {
756
+                $this->sendResponse(tdmtTaskUpd, _("Task Updated:") . " ");
757
+            }
758
+            elseif ($props[$this->props['complete']]) {
759
+                $this->sendResponse(tdmtTaskUpd, _("Task Completed:") . " ");
760
+            }
761
+
762
+            return true;
763
+        }
764
+
765
+        /**
766
+         * Get the store associated with the task.
767
+         *
768
+         * Normally this will just open the store that the processed message is in. However, if the message is opened
769
+         * by a delegate, this function opens the store that the message was delegated from.
770
+         */
771
+        public function getTaskFolderStore() {
772
+            $ownerentryid = false;
773
+
774
+            $rcvdprops = mapi_getprops($this->message, [PR_RCVD_REPRESENTING_ENTRYID]);
775
+            if (isset($rcvdprops[PR_RCVD_REPRESENTING_ENTRYID])) {
776
+                $ownerentryid = $rcvdprops;
777
+            }
778
+
779
+            if (!$ownerentryid) {
780
+                $store = $this->store;
781
+            }
782
+            else {
783
+                $ab = mapi_openaddressbook($this->session);
784
+                if (!$ab) {
785
+                    return false;
786
+                }
787
+
788
+                $mailuser = mapi_ab_openentry($ab, $ownerentryid);
789
+                if (!$mailuser) {
790
+                    return false;
791
+                }
792
+
793
+                $mailuserprops = mapi_getprops($mailuser, [PR_EMAIL_ADDRESS]);
794
+                if (!isset($mailuserprops[PR_EMAIL_ADDRESS])) {
795
+                    return false;
796
+                }
797
+
798
+                $storeid = mapi_msgstore_createentryid($this->store, $mailuserprops[PR_EMAIL_ADDRESS]);
799
+
800
+                $store = mapi_openmsgstore($this->session, $storeid);
801
+            }
802
+
803
+            return $store;
804
+        }
805
+
806
+        /**
807
+         * Open the default task folder for the current user, or the specified user if passed.
808
+         */
809
+        public function getDefaultTasksFolder() {
810
+            $store = $this->getTaskFolderStore();
811
+
812
+            $inbox = mapi_msgstore_getreceivefolder($store);
813
+            $inboxprops = mapi_getprops($inbox, [PR_IPM_TASK_ENTRYID]);
814
+            if (!isset($inboxprops[PR_IPM_TASK_ENTRYID])) {
815
+                return false;
816
+            }
817
+
818
+            return mapi_msgstore_openentry($store, $inboxprops[PR_IPM_TASK_ENTRYID]);
819
+        }
820
+
821
+        /**
822
+         * Function prepare the sent representing properties from given MAPI store.
823
+         *
824
+         * @param $store MAPI store object
825
+         *
826
+         * @return array|bool if store is not mail box owner entryid then
827
+         *                    return false else prepare the sent representing props and return it
828
+         */
829
+        public function getSentReprProps($store) {
830
+            $storeprops = mapi_getprops($store, [PR_MAILBOX_OWNER_ENTRYID]);
831
+            if (!isset($storeprops[PR_MAILBOX_OWNER_ENTRYID])) {
832
+                return false;
833
+            }
834
+
835
+            $ab = mapi_openaddressbook($this->session);
836
+            $mailuser = mapi_ab_openentry($ab, $storeprops[PR_MAILBOX_OWNER_ENTRYID]);
837
+            $mailuserprops = mapi_getprops($mailuser, [PR_ADDRTYPE, PR_EMAIL_ADDRESS, PR_DISPLAY_NAME, PR_SEARCH_KEY, PR_ENTRYID]);
838
+
839
+            $props = [];
840
+            $props[PR_SENT_REPRESENTING_ADDRTYPE] = $mailuserprops[PR_ADDRTYPE];
841
+            $props[PR_SENT_REPRESENTING_EMAIL_ADDRESS] = $mailuserprops[PR_EMAIL_ADDRESS];
842
+            $props[PR_SENT_REPRESENTING_NAME] = $mailuserprops[PR_DISPLAY_NAME];
843
+            $props[PR_SENT_REPRESENTING_SEARCH_KEY] = $mailuserprops[PR_SEARCH_KEY];
844
+            $props[PR_SENT_REPRESENTING_ENTRYID] = $mailuserprops[PR_ENTRYID];
845
+
846
+            return $props;
847
+        }
848
+
849
+        /**
850
+         * Creates an outgoing message based on the passed message - will set delegate information
851
+         * and sent mail folder.
852
+         */
853
+        public function createOutgoingMessage() {
854
+            // Open our default store for this user (that's the only store we can submit in)
855
+            $store = $this->getDefaultStore();
856
+            $storeprops = mapi_getprops($store, [PR_IPM_OUTBOX_ENTRYID, PR_IPM_SENTMAIL_ENTRYID]);
857
+
858
+            $outbox = mapi_msgstore_openentry($store, $storeprops[PR_IPM_OUTBOX_ENTRYID]);
859
+            if (!$outbox) {
860
+                return false;
861
+            }
862
+
863
+            $outgoing = mapi_folder_createmessage($outbox);
864
+            if (!$outgoing) {
865
+                return false;
866
+            }
867
+
868
+            // Set SENT_REPRESENTING in case we're sending as a delegate
869
+            $ownerstore = $this->getTaskFolderStore();
870
+            $sentreprprops = $this->getSentReprProps($ownerstore);
871
+            mapi_setprops($outgoing, $sentreprprops);
872
+
873
+            mapi_setprops($outgoing, [PR_SENTMAIL_ENTRYID => $storeprops[PR_IPM_SENTMAIL_ENTRYID]]);
874
+
875
+            return $outgoing;
876
+        }
877
+
878
+        /**
879
+         * Send a response message (from assignee back to organizer).
880
+         *
881
+         * @param $type int Type of response (tdmtTaskAcc, tdmtTaskDec, tdmtTaskUpd);
882
+         * @param mixed $prefix
883
+         *
884
+         * @return bool TRUE on success
885
+         */
886
+        public function sendResponse($type, $prefix) {
887
+            // Create a message in our outbox
888
+            $outgoing = $this->createOutgoingMessage();
889
+            $messageprops = mapi_getprops($this->message, [PR_CONVERSATION_TOPIC, PR_MESSAGE_CLASS, $this->props['complete']]);
890
+
891
+            $attach = mapi_message_createattach($outgoing);
892
+            mapi_setprops($attach, [PR_ATTACH_METHOD => ATTACH_EMBEDDED_MSG, PR_DISPLAY_NAME => $messageprops[PR_CONVERSATION_TOPIC], PR_ATTACHMENT_HIDDEN => true]);
893
+            $sub = mapi_attach_openproperty($attach, PR_ATTACH_DATA_OBJ, IID_IMessage, 0, MAPI_CREATE | MAPI_MODIFY);
894
+
895
+            $message = !$this->isTaskRequest() ? $this->message : $this->getAssociatedTask(false);
896
+
897
+            $ignoreProps = [PR_ICON_INDEX, $this->props["categories"], PR_SENT_REPRESENTING_NAME, PR_SENT_REPRESENTING_EMAIL_ADDRESS, PR_SENT_REPRESENTING_ADDRTYPE, PR_SENT_REPRESENTING_ENTRYID, PR_SENT_REPRESENTING_SEARCH_KEY];
898
+
899
+            mapi_copyto($message, [], $ignoreProps, $outgoing);
900
+            mapi_copyto($message, [], [], $sub);
901
+
902
+            if (!$this->setRecipientsForResponse($outgoing, $type)) {
903
+                return false;
904
+            }
905
+
906
+            $props = [];
907
+
908
+            switch ($type) {
909
+                case tdmtTaskAcc:
910
+                    $props[PR_MESSAGE_CLASS] = "IPM.TaskRequest.Accept";
911
+                    mapi_setprops($sub, [PR_ICON_INDEX => ICON_TASK_ASSIGNER]);
912
+
913
+                    break;
914
+
915
+                case tdmtTaskDec:
916
+                    $props[PR_MESSAGE_CLASS] = "IPM.TaskRequest.Decline";
917
+                    mapi_setprops($sub, [PR_ICON_INDEX => ICON_TASK_DECLINE]);
918
+
919
+                    break;
920
+
921
+                case tdmtTaskUpd:
922
+                    mapi_setprops($sub, [PR_ICON_INDEX => ICON_TASK_ASSIGNER]);
923
+                    if ($messageprops[$this->props['complete']]) {
924
+                        $props[PR_MESSAGE_CLASS] = "IPM.TaskRequest.Complete";
925
+                    }
926
+                    else {
927
+                        $props[PR_MESSAGE_CLASS] = "IPM.TaskRequest.Update";
928
+                    }
929
+
930
+                    break;
931
+            }
932
+
933
+            mapi_savechanges($sub);
934
+            mapi_savechanges($attach);
935
+
936
+            $props[PR_SUBJECT] = $prefix . $messageprops[PR_CONVERSATION_TOPIC];
937
+            $props[$this->props['taskmode']] = $type;
938
+            $props[$this->props['task_assigned_time']] = time();
939
+
940
+            mapi_setprops($outgoing, $props);
941
+
942
+            // taskCommentsInfo contains some comments which added by assignee while
943
+            // edit response before sending task response.
944
+            if ($this->taskCommentsInfo) {
945
+                $comments = $this->getTaskCommentsInfo();
946
+                $stream = mapi_openproperty($outgoing, PR_BODY, IID_IStream, STGM_TRANSACTED, MAPI_CREATE | MAPI_MODIFY);
947
+                mapi_stream_setsize($stream, strlen($comments));
948
+                mapi_stream_write($stream, $comments);
949
+                mapi_stream_commit($stream);
950
+            }
951
+
952
+            mapi_savechanges($outgoing);
953
+            mapi_message_submitmessage($outgoing);
954
+
955
+            return true;
956
+        }
957
+
958
+        public function getDefaultStore() {
959
+            $table = mapi_getmsgstorestable($this->session);
960
+            $rows = mapi_table_queryallrows($table, [PR_DEFAULT_STORE, PR_ENTRYID]);
961
+
962
+            foreach ($rows as $row) {
963
+                if ($row[PR_DEFAULT_STORE]) {
964
+                    return mapi_openmsgstore($this->session, $row[PR_ENTRYID]);
965
+                }
966
+            }
967
+
968
+            return false;
969
+        }
970
+
971
+        /**
972
+         * Creates a new TaskGlobalObjId.
973
+         *
974
+         * Just 16 bytes of random data
975
+         */
976
+        public function createTGOID() {
977
+            $goid = "";
978
+            for ($i = 0; $i < 16; ++$i) {
979
+                $goid .= chr(rand(0, 255));
980
+            }
981
+
982
+            return $goid;
983
+        }
984
+
985
+        /**
986
+         * Function used to get the embedded task of task request. Which further used to
987
+         * Create/Update associated task of assigner/assignee.
988
+         *
989
+         * @param object $message which contains embedded task
990
+         *
991
+         * @return false|object $task if found embedded task else false
992
+         */
993
+        public function getEmbeddedTask($message) {
994
+            $task = false;
995
+            $goid = mapi_getprops($message, [$this->props["task_goid"]]);
996
+            $attachmentTable = mapi_message_getattachmenttable($message);
997
+            $restriction = [
998
+                RES_PROPERTY,
999
+                [
1000
+                    RELOP => RELOP_EQ,
1001
+                    ULPROPTAG => PR_ATTACH_METHOD,
1002
+                    VALUE => ATTACH_EMBEDDED_MSG, ],
1003
+            ];
1004
+            $rows = mapi_table_queryallrows($attachmentTable, [PR_ATTACH_NUM], $restriction);
1005
+
1006
+            if (empty($rows)) {
1007
+                return $task;
1008
+            }
1009
+
1010
+            foreach ($rows as $row) {
1011
+                try {
1012
+                    $attach = mapi_message_openattach($message, $row[PR_ATTACH_NUM]);
1013
+                    $task = mapi_attach_openobj($attach);
1014
+                }
1015
+                catch (MAPIException $e) {
1016
+                    continue;
1017
+                }
1018
+
1019
+                $taskGoid = mapi_getprops($task, [$this->props["task_goid"]]);
1020
+                if ($goid[$this->props["task_goid"]] === $taskGoid[$this->props["task_goid"]]) {
1021
+                    mapi_setprops($attach, [PR_ATTACHMENT_HIDDEN => true]);
1022
+                    mapi_savechanges($attach);
1023
+                    mapi_savechanges($message);
1024
+
1025
+                    break;
1026
+                }
1027
+            }
1028
+
1029
+            return $task;
1030
+        }
1031
+
1032
+        /**
1033
+         * Function was used to set the user name who has last used this task also it was
1034
+         * update the  tasklastdelegate and task_assigned_time.
1035
+         */
1036
+        public function setLastUser() {
1037
+            $delegatestore = $this->getDefaultStore();
1038
+            $taskstore = $this->getTaskFolderStore();
1039
+
1040
+            $delegateprops = mapi_getprops($delegatestore, [PR_MAILBOX_OWNER_NAME]);
1041
+            $taskprops = mapi_getprops($taskstore, [PR_MAILBOX_OWNER_NAME]);
1042
+
1043
+            // The owner of the task
1044
+            $username = $delegateprops[PR_MAILBOX_OWNER_NAME];
1045
+            // This is me (the one calling the script)
1046
+            $delegate = $taskprops[PR_MAILBOX_OWNER_NAME];
1047
+
1048
+            if ($this->isTaskRequest()) {
1049
+                $task = $this->getAssociatedTask(false);
1050
+                mapi_setprops($task, [$this->props["tasklastuser"] => $username, $this->props["tasklastdelegate"] => $delegate, $this->props['task_assigned_time'] => time()]);
1051
+                mapi_savechanges($task);
1052
+            }
1053
+            mapi_setprops($this->message, [$this->props["tasklastuser"] => $username, $this->props["tasklastdelegate"] => $delegate, $this->props['task_assigned_time'] => time()]);
1054
+        }
1055
+
1056
+        /**
1057
+         * Assignee becomes the owner when a user/assignor assigns any task to someone. Also there can be more than one assignee.
1058
+         * This function sets assignee as owner in the assignor's copy of task.
1059
+         */
1060
+        public function setOwnerForAssignor() {
1061
+            $recipTable = mapi_message_getrecipienttable($this->message);
1062
+            $recips = mapi_table_queryallrows($recipTable, [PR_DISPLAY_NAME]);
1063
+
1064
+            if (!empty($recips)) {
1065
+                $owner = [];
1066
+                foreach ($recips as $value) {
1067
+                    $owner[] = $value[PR_DISPLAY_NAME];
1068
+                }
1069
+
1070
+                $props = [$this->props['owner'] => implode("; ", $owner)];
1071
+                mapi_setprops($this->message, $props);
1072
+            }
1073
+        }
1074
+
1075
+        /**
1076
+         * Sets assignor as recipients in assignee's copy of task.
1077
+         *
1078
+         * If assignor has requested task updates then the assignor is added as recipient type MAPI_CC.
1079
+         *
1080
+         * Also if assignor has request SOC then the assignor is also add as recipient type MAPI_BCC
1081
+         *
1082
+         * @param $task message MAPI message which assignee's copy of task
1083
+         */
1084
+        public function setAssignorInRecipients($task) {
1085
+            $recipTable = mapi_message_getrecipienttable($task);
1086
+
1087
+            // Delete all MAPI_TO recipients
1088
+            $recips = mapi_table_queryallrows($recipTable, [PR_ROWID], [
1089
+                RES_PROPERTY,
1090
+                [
1091
+                    RELOP => RELOP_EQ,
1092
+                    ULPROPTAG => PR_RECIPIENT_TYPE,
1093
+                    VALUE => MAPI_TO,
1094
+                ], ]);
1095
+            foreach ($recips as $recip) {
1096
+                mapi_message_modifyrecipients($task, MODRECIP_REMOVE, [$recip]);
1097
+            }
1098
+
1099
+            $recips = [];
1100
+            $taskReqProps = mapi_getprops($this->message, [PR_SENT_REPRESENTING_NAME, PR_SENT_REPRESENTING_EMAIL_ADDRESS, PR_SENT_REPRESENTING_ENTRYID, PR_SENT_REPRESENTING_ADDRTYPE, PR_SENT_REPRESENTING_SEARCH_KEY]);
1101
+            $associatedTaskProps = mapi_getprops($task, [$this->props['taskupdates'], $this->props['tasksoc'], $this->props['taskmultrecips']]);
1102
+
1103
+            // Build assignor info
1104
+            $assignor = [
1105
+                PR_ENTRYID => $taskReqProps[PR_SENT_REPRESENTING_ENTRYID],
1106
+                PR_DISPLAY_NAME => $taskReqProps[PR_SENT_REPRESENTING_NAME],
1107
+                PR_EMAIL_ADDRESS => $taskReqProps[PR_SENT_REPRESENTING_EMAIL_ADDRESS],
1108
+                PR_RECIPIENT_DISPLAY_NAME => $taskReqProps[PR_SENT_REPRESENTING_NAME],
1109
+                PR_ADDRTYPE => empty($taskReqProps[PR_SENT_REPRESENTING_ADDRTYPE]) ? 'SMTP' : $taskReqProps[PR_SENT_REPRESENTING_ADDRTYPE],
1110
+                PR_RECIPIENT_FLAGS => recipSendable,
1111
+                PR_SEARCH_KEY => $taskReqProps[PR_SENT_REPRESENTING_SEARCH_KEY],
1112
+            ];
1113
+
1114
+            // Assignor has requested task updates, so set him/her as MAPI_CC in recipienttable.
1115
+            if ((isset($associatedTaskProps[$this->props['taskupdates']]) && $associatedTaskProps[$this->props['taskupdates']]) &&
1116
+                !(isset($associatedTaskProps[$this->props['taskmultrecips']]) && $associatedTaskProps[$this->props['taskmultrecips']] == tmrReceived)) {
1117
+                $assignor[PR_RECIPIENT_TYPE] = MAPI_CC;
1118
+                $recips[] = $assignor;
1119
+            }
1120
+
1121
+            // Assignor wants to receive an email report when task is mark as 'Complete', so in recipients as MAPI_BCC
1122
+            if ($associatedTaskProps[$this->props['tasksoc']]) {
1123
+                $assignor[PR_RECIPIENT_TYPE] = MAPI_BCC;
1124
+                $recips[] = $assignor;
1125
+            }
1126
+
1127
+            if (!empty($recips)) {
1128
+                mapi_message_modifyrecipients($task, MODRECIP_ADD, $recips);
1129
+            }
1130
+        }
1131
+
1132
+        /**
1133
+         * Deletes incoming task request from Inbox.
1134
+         *
1135
+         * @returns array returns PR_ENTRYID, PR_STORE_ENTRYID and PR_PARENT_ENTRYID of the deleted task request
1136
+         */
1137
+        public function deleteReceivedTR() {
1138
+            $store = $this->getTaskFolderStore();
1139
+            $storeType = mapi_getprops($store, [PR_MDB_PROVIDER]);
1140
+            if ($storeType[PR_MDB_PROVIDER] === ZARAFA_STORE_PUBLIC_GUID) {
1141
+                $store = $this->getDefaultStore();
1142
+            }
1143
+            $inbox = mapi_msgstore_getreceivefolder($store);
1144
+
1145
+            $storeProps = mapi_getprops($store, [PR_IPM_WASTEBASKET_ENTRYID]);
1146
+            $props = mapi_getprops($this->message, [$this->props['task_goid']]);
1147
+            $goid = $props[$this->props['task_goid']];
1148
+
1149
+            // Find the task by looking for the task_goid
1150
+            $restriction = [
1151
+                RES_PROPERTY,
1152
+                [
1153
+                    RELOP => RELOP_EQ,
1154
+                    ULPROPTAG => $this->props['task_goid'],
1155
+                    VALUE => $goid, ],
1156
+            ];
1157
+
1158
+            $contents = mapi_folder_getcontentstable($inbox);
1159
+
1160
+            $rows = mapi_table_queryallrows($contents, [PR_ENTRYID, PR_PARENT_ENTRYID, PR_STORE_ENTRYID], $restriction);
1161
+
1162
+            if (!empty($rows)) {
1163
+                // If there are multiple, just use the first
1164
+                $entryid = $rows[0][PR_ENTRYID];
1165
+                $wastebasket = mapi_msgstore_openentry($store, $storeProps[PR_IPM_WASTEBASKET_ENTRYID]);
1166
+                mapi_folder_copymessages($inbox, [$entryid], $wastebasket, MESSAGE_MOVE);
1167
+
1168
+                return [PR_ENTRYID => $entryid, PR_PARENT_ENTRYID => $rows[0][PR_PARENT_ENTRYID], PR_STORE_ENTRYID => $rows[0][PR_STORE_ENTRYID]];
1169
+            }
1170
+
1171
+            return false;
1172
+        }
1173
+
1174
+        /**
1175
+         * Sets recipients for the outgoing message according to type of the response.
1176
+         *
1177
+         * If it is a task update, then only recipient type MAPI_CC are taken from the task message.
1178
+         *
1179
+         * If it is accept/decline response, then PR_SENT_REPRESENTATING_XXXX are taken as recipient.
1180
+         *
1181
+         *@param $outgoing MAPI_message outgoing mapi message
1182
+         *@param $responseType String response type
1183
+         */
1184
+        public function setRecipientsForResponse($outgoing, $responseType) {
1185
+            // Clear recipients from outgoing msg
1186
+            $this->deleteAllRecipients($outgoing);
1187
+
1188
+            // If it is a task update then get MAPI_CC recipients which are assignors who has asked for task update.
1189
+            if ($responseType == tdmtTaskUpd) {
1190
+                $props = mapi_getprops($this->message, [$this->props['complete']]);
1191
+                $isComplete = $props[$this->props['complete']];
1192
+
1193
+                $recipTable = mapi_message_getrecipienttable($this->message);
1194
+                $recips = mapi_table_queryallrows($recipTable, $this->recipProps, [
1195
+                    RES_PROPERTY,
1196
+                    [
1197
+                        RELOP => RELOP_EQ,
1198
+                        ULPROPTAG => PR_RECIPIENT_TYPE,
1199
+                        VALUE => ($isComplete ? MAPI_BCC : MAPI_CC),
1200
+                    ],
1201
+                ]);
1202
+
1203
+                // No recipients found, return error
1204
+                if (empty($recips)) {
1205
+                    return false;
1206
+                }
1207
+
1208
+                foreach ($recips as $recip) {
1209
+                    $recip[PR_RECIPIENT_TYPE] = MAPI_TO;    // Change recipient type to MAPI_TO
1210
+                    mapi_message_modifyrecipients($outgoing, MODRECIP_ADD, [$recip]);
1211
+                }
1212
+
1213
+                return true;
1214
+            }
1215
+
1216
+            $orgprops = mapi_getprops($this->message, [PR_SENT_REPRESENTING_NAME, PR_SENT_REPRESENTING_EMAIL_ADDRESS, PR_SENT_REPRESENTING_ADDRTYPE, PR_SENT_REPRESENTING_ENTRYID, PR_SUBJECT]);
1217
+            $recip = [
1218
+                PR_DISPLAY_NAME => $orgprops[PR_SENT_REPRESENTING_NAME],
1219
+                PR_EMAIL_ADDRESS => $orgprops[PR_SENT_REPRESENTING_EMAIL_ADDRESS],
1220
+                PR_ADDRTYPE => $orgprops[PR_SENT_REPRESENTING_ADDRTYPE],
1221
+                PR_ENTRYID => $orgprops[PR_SENT_REPRESENTING_ENTRYID],
1222
+                PR_RECIPIENT_TYPE => MAPI_TO, ];
1223
+
1224
+            mapi_message_modifyrecipients($outgoing, MODRECIP_ADD, [$recip]);
1225
+
1226
+            return true;
1227
+        }
1228
+
1229
+        /**
1230
+         * Deletes all recipients from given message object.
1231
+         *
1232
+         * @param $message MAPI message from which recipients are to be removed
1233
+         */
1234
+        public function deleteAllRecipients($message) {
1235
+            $recipTable = mapi_message_getrecipienttable($message);
1236
+            $recipRows = mapi_table_queryallrows($recipTable, [PR_ROWID]);
1237
+
1238
+            foreach ($recipRows as $recipient) {
1239
+                mapi_message_modifyrecipients($message, MODRECIP_REMOVE, [$recipient]);
1240
+            }
1241
+        }
1242
+
1243
+        /**
1244
+         * Function used to mark the record to complete and send complete update
1245
+         * notification to assigner.
1246
+         *
1247
+         * @return bool TRUE if the update succeeded, FALSE otherwise
1248
+         */
1249
+        public function sendCompleteUpdate() {
1250
+            $messageprops = mapi_getprops($this->message, [$this->props['taskstate']]);
1251
+
1252
+            if (!isset($messageprops[$this->props['taskstate']]) || $messageprops[$this->props['taskstate']] != tdsOWN) {
1253
+                return false; // Can only decline assignee task
1254
+            }
1255
+
1256
+            mapi_setprops(
1257
+                $this->message,
1258
+                [
1259
+                    $this->props['complete'] => true,
1260
+                    $this->props['datecompleted'] => time(),
1261
+                    $this->props['status'] => 2,
1262
+                    $this->props['percent_complete'] => 1, ]
1263
+            );
1264
+
1265
+            return $this->doUpdate();
1266
+        }
1267
+
1268
+        /**
1269
+         * Function returns extra info about task request comments along with message body
1270
+         * which will be included in body while sending task request/response.
1271
+         *
1272
+         * @return string info about task request comments along with message body
1273
+         */
1274
+        public function getTaskCommentsInfo() {
1275
+            return $this->taskCommentsInfo;
1276
+        }
1277
+
1278
+        /**
1279
+         * Function sets extra info about task request comments along with message body
1280
+         * which will be included in body while sending task request/response.
1281
+         *
1282
+         * @param string $taskCommentsInfo info about task request comments along with message body
1283
+         */
1284
+        public function setTaskCommentsInfo($taskCommentsInfo) {
1285
+            $this->taskCommentsInfo = $taskCommentsInfo;
1286
+        }
1287
+    }
Please login to merge, or discard this patch.
Spacing   +39 added lines, -39 removed lines patch added patch discarded remove patch
@@ -23,12 +23,12 @@  discard block
 block discarded – undo
23 23
 	 * carried in the IPM.TaskRequest item (although this information seems
24 24
 	 * redundant due to that information already being available in PR_MESSAGE_CLASS).
25 25
 	 */
26
-	define('tdmtNothing', 0);            // Value in IPM.Task items
27
-	define('tdmtTaskReq', 1);            // Assigner -> Assignee
28
-	define('tdmtTaskAcc', 2);            // Assignee -> Assigner
29
-	define('tdmtTaskDec', 3);            // Assignee -> Assigner
30
-	define('tdmtTaskUpd', 4);            // Assignee -> Assigner
31
-	define('tdmtTaskSELF', 5);            // Assigner -> Assigner (?)
26
+	define('tdmtNothing', 0); // Value in IPM.Task items
27
+	define('tdmtTaskReq', 1); // Assigner -> Assignee
28
+	define('tdmtTaskAcc', 2); // Assignee -> Assigner
29
+	define('tdmtTaskDec', 3); // Assignee -> Assigner
30
+	define('tdmtTaskUpd', 4); // Assignee -> Assigner
31
+	define('tdmtTaskSELF', 5); // Assigner -> Assigner (?)
32 32
 
33 33
 	/* The TaskHistory is used to show the last action on the task
34 34
 	 * on both the assigner and the assignee's side.
@@ -38,22 +38,22 @@  discard block
 block discarded – undo
38 38
 	 * the format 'Accepted by <user> on 01-01-2010 11:00'.
39 39
 	 */
40 40
 	define('thNone', 0);
41
-	define('thAccepted', 1);            // Set by assignee
42
-	define('thDeclined', 2);            // Set by assignee
43
-	define('thUpdated', 3);                // Set by assignee
41
+	define('thAccepted', 1); // Set by assignee
42
+	define('thDeclined', 2); // Set by assignee
43
+	define('thUpdated', 3); // Set by assignee
44 44
 	define('thDueDateChanged', 4);
45
-	define('thAssigned', 5);            // Set by assigner
45
+	define('thAssigned', 5); // Set by assigner
46 46
 
47 47
 	/* The TaskState value is used to differentiate the version of a task
48 48
 	 * in the assigner's folder and the version in the
49 49
 	 * assignee's folder. The buttons shown depend on this and
50 50
 	 * the 'taskaccepted' boolean (for the assignee)
51 51
 	 */
52
-	define('tdsNOM', 0);        // Got a response to a deleted task, and re-created the task for the assigner
53
-	define('tdsOWNNEW', 1);        // Not assigned
54
-	define('tdsOWN', 2);        // Assignee version
55
-	define('tdsACC', 3);        // Assigner version
56
-	define('tdsDEC', 4);        // Assigner version, but assignee declined
52
+	define('tdsNOM', 0); // Got a response to a deleted task, and re-created the task for the assigner
53
+	define('tdsOWNNEW', 1); // Not assigned
54
+	define('tdsOWN', 2); // Assignee version
55
+	define('tdsACC', 3); // Assigner version
56
+	define('tdsDEC', 4); // Assigner version, but assignee declined
57 57
 
58 58
 	/* The TaskAcceptanceState is used for the assigner to indicate state */
59 59
 	define('olTaskNotDelegated', 0);
@@ -63,13 +63,13 @@  discard block
 block discarded – undo
63 63
 
64 64
 	/* The task ownership indicates the role of the current user relative to the task. */
65 65
 	define('olNewTask', 0);
66
-	define('olDelegatedTask', 1);    // Task has been assigned
67
-	define('olOwnTask', 2);            // Task owned
66
+	define('olDelegatedTask', 1); // Task has been assigned
67
+	define('olOwnTask', 2); // Task owned
68 68
 
69 69
 	/* taskmultrecips indicates whether the task request sent or received has multiple assignees or not. */
70 70
 	define('tmrNone', 0);
71
-	define('tmrSent', 1);        // Task has been sent to multiple assignee
72
-	define('tmrReceived', 2);    // Task Request received has multiple assignee
71
+	define('tmrSent', 1); // Task has been sent to multiple assignee
72
+	define('tmrReceived', 2); // Task Request received has multiple assignee
73 73
 
74 74
 	// Task icon index.
75 75
 	define('ICON_TASK_ASSIGNEE', 0x00000502);
@@ -307,7 +307,7 @@  discard block
 block discarded – undo
307 307
 					VALUE => $goid, ],
308 308
 				];
309 309
 
310
-				$table = mapi_folder_getcontentstable($folder, MAPI_DEFERRED_ERRORS | SHOW_SOFT_DELETES);
310
+				$table = mapi_folder_getcontentstable($folder, MAPI_DEFERRED_ERRORS|SHOW_SOFT_DELETES);
311 311
 				$softDeletedItems = mapi_table_queryallrows($table, [PR_ENTRYID], $restriction);
312 312
 				if (!empty($softDeletedItems)) {
313 313
 					return true;
@@ -515,14 +515,14 @@  discard block
 block discarded – undo
515 515
 			// Set properties on Task Request
516 516
 			mapi_setprops($this->message, [
517 517
 				$this->props['task_goid'] => $taskid, /* our new task_goid */
518
-				$this->props['taskstate'] => tdsACC,         /* state for our outgoing request */
519
-				$this->props['taskmode'] => tdmtNothing,     /* we're not sending a change */
520
-				$this->props['updatecount'] => 2,            /* version 2 (no idea) */
518
+				$this->props['taskstate'] => tdsACC, /* state for our outgoing request */
519
+				$this->props['taskmode'] => tdmtNothing, /* we're not sending a change */
520
+				$this->props['updatecount'] => 2, /* version 2 (no idea) */
521 521
 				$this->props['task_acceptance_state'] => olTaskDelegationUnknown, /* no reply yet */
522 522
 				$this->props['ownership'] => olDelegatedTask, /* Task has been assigned */
523
-				$this->props['taskhistory'] => thAssigned,    /* Task has been assigned */
523
+				$this->props['taskhistory'] => thAssigned, /* Task has been assigned */
524 524
 				PR_CONVERSATION_TOPIC => $messageprops[PR_SUBJECT],
525
-				PR_ICON_INDEX => ICON_TASK_ASSIGNER,         /* Task request icon */
525
+				PR_ICON_INDEX => ICON_TASK_ASSIGNER, /* Task request icon */
526 526
 			]);
527 527
 			$this->setLastUser();
528 528
 			$this->setOwnerForAssignor();
@@ -537,12 +537,12 @@  discard block
 block discarded – undo
537 537
 
538 538
 			// Make it a task request, and put it in sent items after it is sent
539 539
 			mapi_setprops($outgoing, [
540
-				PR_MESSAGE_CLASS => "IPM.TaskRequest",         /* class is task request */
541
-				$this->props['taskstate'] => tdsOWN,         /* for the recipient he is the task owner */
542
-				$this->props['taskmode'] => tdmtTaskReq,    /* for the recipient it's a request */
543
-				$this->props['updatecount'] => 1,            /* version 2 is in the attachment */
540
+				PR_MESSAGE_CLASS => "IPM.TaskRequest", /* class is task request */
541
+				$this->props['taskstate'] => tdsOWN, /* for the recipient he is the task owner */
542
+				$this->props['taskmode'] => tdmtTaskReq, /* for the recipient it's a request */
543
+				$this->props['updatecount'] => 1, /* version 2 is in the attachment */
544 544
 				PR_SUBJECT_PREFIX => $prefix,
545
-				PR_SUBJECT => $prefix . $messageprops[PR_SUBJECT],
545
+				PR_SUBJECT => $prefix.$messageprops[PR_SUBJECT],
546 546
 			]);
547 547
 
548 548
 			$attach = mapi_message_createattach($outgoing);
@@ -551,7 +551,7 @@  discard block
 block discarded – undo
551 551
 				PR_ATTACHMENT_HIDDEN => true,
552 552
 				PR_DISPLAY_NAME => $messageprops[PR_SUBJECT], ]);
553 553
 
554
-			$sub = mapi_attach_openproperty($attach, PR_ATTACH_DATA_OBJ, IID_IMessage, 0, MAPI_MODIFY | MAPI_CREATE);
554
+			$sub = mapi_attach_openproperty($attach, PR_ATTACH_DATA_OBJ, IID_IMessage, 0, MAPI_MODIFY|MAPI_CREATE);
555 555
 
556 556
 			mapi_copyto($this->message, [], [], $sub);
557 557
 			mapi_savechanges($sub);
@@ -649,7 +649,7 @@  discard block
 block discarded – undo
649 649
 		 * @return entryid EntryID of the accepted task
650 650
 		 */
651 651
 		public function doAccept() {
652
-			$prefix = _("Task Accepted:") . " ";
652
+			$prefix = _("Task Accepted:")." ";
653 653
 			$messageProps = mapi_getprops($this->message, [PR_MESSAGE_CLASS, $this->props['taskstate']]);
654 654
 
655 655
 			if (!isset($messageProps[$this->props['taskstate']]) || $messageProps[$this->props['taskstate']] != tdsOWN) {
@@ -698,7 +698,7 @@  discard block
 block discarded – undo
698 698
 		 * @return boolean TRUE on success, FALSE on failure
699 699
 		 */
700 700
 		public function doDecline() {
701
-			$prefix = _("Task Declined:") . " ";
701
+			$prefix = _("Task Declined:")." ";
702 702
 			$messageProps = mapi_getprops($this->message, [$this->props['taskstate']]);
703 703
 
704 704
 			if (!isset($messageProps[$this->props['taskstate']]) || $messageProps[$this->props['taskstate']] != tdsOWN) {
@@ -753,10 +753,10 @@  discard block
 block discarded – undo
753 753
 
754 754
 			$props = mapi_getprops($this->message, [$this->props['taskupdates'], $this->props['tasksoc'], $this->props['recurring'], $this->props['complete']]);
755 755
 			if (!$props[$this->props['complete']] && $props[$this->props['taskupdates']] && !(isset($props[$this->props['recurring']]) && $props[$this->props['recurring']])) {
756
-				$this->sendResponse(tdmtTaskUpd, _("Task Updated:") . " ");
756
+				$this->sendResponse(tdmtTaskUpd, _("Task Updated:")." ");
757 757
 			}
758 758
 			elseif ($props[$this->props['complete']]) {
759
-				$this->sendResponse(tdmtTaskUpd, _("Task Completed:") . " ");
759
+				$this->sendResponse(tdmtTaskUpd, _("Task Completed:")." ");
760 760
 			}
761 761
 
762 762
 			return true;
@@ -890,7 +890,7 @@  discard block
 block discarded – undo
890 890
 
891 891
 			$attach = mapi_message_createattach($outgoing);
892 892
 			mapi_setprops($attach, [PR_ATTACH_METHOD => ATTACH_EMBEDDED_MSG, PR_DISPLAY_NAME => $messageprops[PR_CONVERSATION_TOPIC], PR_ATTACHMENT_HIDDEN => true]);
893
-			$sub = mapi_attach_openproperty($attach, PR_ATTACH_DATA_OBJ, IID_IMessage, 0, MAPI_CREATE | MAPI_MODIFY);
893
+			$sub = mapi_attach_openproperty($attach, PR_ATTACH_DATA_OBJ, IID_IMessage, 0, MAPI_CREATE|MAPI_MODIFY);
894 894
 
895 895
 			$message = !$this->isTaskRequest() ? $this->message : $this->getAssociatedTask(false);
896 896
 
@@ -933,7 +933,7 @@  discard block
 block discarded – undo
933 933
 			mapi_savechanges($sub);
934 934
 			mapi_savechanges($attach);
935 935
 
936
-			$props[PR_SUBJECT] = $prefix . $messageprops[PR_CONVERSATION_TOPIC];
936
+			$props[PR_SUBJECT] = $prefix.$messageprops[PR_CONVERSATION_TOPIC];
937 937
 			$props[$this->props['taskmode']] = $type;
938 938
 			$props[$this->props['task_assigned_time']] = time();
939 939
 
@@ -943,7 +943,7 @@  discard block
 block discarded – undo
943 943
 			// edit response before sending task response.
944 944
 			if ($this->taskCommentsInfo) {
945 945
 				$comments = $this->getTaskCommentsInfo();
946
-				$stream = mapi_openproperty($outgoing, PR_BODY, IID_IStream, STGM_TRANSACTED, MAPI_CREATE | MAPI_MODIFY);
946
+				$stream = mapi_openproperty($outgoing, PR_BODY, IID_IStream, STGM_TRANSACTED, MAPI_CREATE|MAPI_MODIFY);
947 947
 				mapi_stream_setsize($stream, strlen($comments));
948 948
 				mapi_stream_write($stream, $comments);
949 949
 				mapi_stream_commit($stream);
@@ -1206,7 +1206,7 @@  discard block
 block discarded – undo
1206 1206
 				}
1207 1207
 
1208 1208
 				foreach ($recips as $recip) {
1209
-					$recip[PR_RECIPIENT_TYPE] = MAPI_TO;    // Change recipient type to MAPI_TO
1209
+					$recip[PR_RECIPIENT_TYPE] = MAPI_TO; // Change recipient type to MAPI_TO
1210 1210
 					mapi_message_modifyrecipients($outgoing, MODRECIP_ADD, [$recip]);
1211 1211
 				}
1212 1212
 
Please login to merge, or discard this patch.
Braces   +6 added lines, -12 removed lines patch added patch discarded remove patch
@@ -271,8 +271,7 @@  discard block
 block discarded – undo
271 271
 				// Copy sender information from the e-mail
272 272
 				$props = mapi_getprops($this->message, $senderProps);
273 273
 				mapi_setprops($task, $props);
274
-			}
275
-			else {
274
+			} else {
276 275
 				// If there are multiple, just use the first
277 276
 				$entryid = $rows[0][PR_ENTRYID];
278 277
 
@@ -575,8 +574,7 @@  discard block
 block discarded – undo
575 574
 
576 575
 			if (isset($messageprops)) {
577 576
 				++$messageprops[$this->props['updatecount']];
578
-			}
579
-			else {
577
+			} else {
580 578
 				$messageprops[$this->props['updatecount']] = 1;
581 579
 			}
582 580
 
@@ -754,8 +752,7 @@  discard block
 block discarded – undo
754 752
 			$props = mapi_getprops($this->message, [$this->props['taskupdates'], $this->props['tasksoc'], $this->props['recurring'], $this->props['complete']]);
755 753
 			if (!$props[$this->props['complete']] && $props[$this->props['taskupdates']] && !(isset($props[$this->props['recurring']]) && $props[$this->props['recurring']])) {
756 754
 				$this->sendResponse(tdmtTaskUpd, _("Task Updated:") . " ");
757
-			}
758
-			elseif ($props[$this->props['complete']]) {
755
+			} elseif ($props[$this->props['complete']]) {
759 756
 				$this->sendResponse(tdmtTaskUpd, _("Task Completed:") . " ");
760 757
 			}
761 758
 
@@ -778,8 +775,7 @@  discard block
 block discarded – undo
778 775
 
779 776
 			if (!$ownerentryid) {
780 777
 				$store = $this->store;
781
-			}
782
-			else {
778
+			} else {
783 779
 				$ab = mapi_openaddressbook($this->session);
784 780
 				if (!$ab) {
785 781
 					return false;
@@ -922,8 +918,7 @@  discard block
 block discarded – undo
922 918
 					mapi_setprops($sub, [PR_ICON_INDEX => ICON_TASK_ASSIGNER]);
923 919
 					if ($messageprops[$this->props['complete']]) {
924 920
 						$props[PR_MESSAGE_CLASS] = "IPM.TaskRequest.Complete";
925
-					}
926
-					else {
921
+					} else {
927 922
 						$props[PR_MESSAGE_CLASS] = "IPM.TaskRequest.Update";
928 923
 					}
929 924
 
@@ -1011,8 +1006,7 @@  discard block
 block discarded – undo
1011 1006
 				try {
1012 1007
 					$attach = mapi_message_openattach($message, $row[PR_ATTACH_NUM]);
1013 1008
 					$task = mapi_attach_openobj($attach);
1014
-				}
1015
-				catch (MAPIException $e) {
1009
+				} catch (MAPIException $e) {
1016 1010
 					continue;
1017 1011
 				}
1018 1012
 
Please login to merge, or discard this patch.
grommunio-sync-top.php 3 patches
Indentation   +759 added lines, -759 removed lines patch added patch discarded remove patch
@@ -11,7 +11,7 @@  discard block
 block discarded – undo
11 11
 
12 12
 require_once 'vendor/autoload.php';
13 13
 if (!defined('GSYNC_CONFIG')) {
14
-	define('GSYNC_CONFIG', 'config.php');
14
+    define('GSYNC_CONFIG', 'config.php');
15 15
 }
16 16
 
17 17
 include_once GSYNC_CONFIG;
@@ -19,777 +19,777 @@  discard block
 block discarded – undo
19 19
 /*
20 20
  * MAIN
21 21
  */
22
-	declare(ticks=1);
23
-	define('BASE_PATH_CLI', dirname(__FILE__) . "/");
24
-	set_include_path(get_include_path() . PATH_SEPARATOR . BASE_PATH_CLI);
22
+    declare(ticks=1);
23
+    define('BASE_PATH_CLI', dirname(__FILE__) . "/");
24
+    set_include_path(get_include_path() . PATH_SEPARATOR . BASE_PATH_CLI);
25 25
 
26
-	if (!defined('GSYNC_CONFIG')) {
27
-		define('GSYNC_CONFIG', BASE_PATH_CLI . 'config.php');
28
-	}
26
+    if (!defined('GSYNC_CONFIG')) {
27
+        define('GSYNC_CONFIG', BASE_PATH_CLI . 'config.php');
28
+    }
29 29
 
30
-	include_once GSYNC_CONFIG;
30
+    include_once GSYNC_CONFIG;
31 31
 
32
-	try {
33
-		GSync::CheckConfig();
34
-		if (!function_exists("pcntl_signal")) {
35
-			throw new FatalException("Function pcntl_signal() is not available. Please install package 'php5-pcntl' (or similar) on your system.");
36
-		}
32
+    try {
33
+        GSync::CheckConfig();
34
+        if (!function_exists("pcntl_signal")) {
35
+            throw new FatalException("Function pcntl_signal() is not available. Please install package 'php5-pcntl' (or similar) on your system.");
36
+        }
37 37
 
38
-		if (php_sapi_name() != "cli") {
39
-			throw new FatalException("This script can only be called from the CLI.");
40
-		}
38
+        if (php_sapi_name() != "cli") {
39
+            throw new FatalException("This script can only be called from the CLI.");
40
+        }
41 41
 
42
-		$zpt = new GSyncTop();
42
+        $zpt = new GSyncTop();
43 43
 
44
-		// check if help was requested from CLI
45
-		if (in_array('-h', $argv) || in_array('--help', $argv)) {
46
-			echo $zpt->UsageInstructions();
44
+        // check if help was requested from CLI
45
+        if (in_array('-h', $argv) || in_array('--help', $argv)) {
46
+            echo $zpt->UsageInstructions();
47 47
 
48
-			exit(0);
49
-		}
48
+            exit(0);
49
+        }
50 50
 
51
-		if ($zpt->IsAvailable()) {
52
-			pcntl_signal(SIGINT, [$zpt, "SignalHandler"]);
53
-			$zpt->run();
54
-			$zpt->scrClear();
55
-			system("stty sane");
56
-		}
57
-		else {
58
-			echo "grommunio-sync interprocess communication (IPC) is not available or TopCollector is disabled.\n";
59
-		}
60
-	}
61
-	catch (GSyncException $zpe) {
62
-		fwrite(STDERR, get_class($zpe) . ": " . $zpe->getMessage() . "\n");
51
+        if ($zpt->IsAvailable()) {
52
+            pcntl_signal(SIGINT, [$zpt, "SignalHandler"]);
53
+            $zpt->run();
54
+            $zpt->scrClear();
55
+            system("stty sane");
56
+        }
57
+        else {
58
+            echo "grommunio-sync interprocess communication (IPC) is not available or TopCollector is disabled.\n";
59
+        }
60
+    }
61
+    catch (GSyncException $zpe) {
62
+        fwrite(STDERR, get_class($zpe) . ": " . $zpe->getMessage() . "\n");
63 63
 
64
-		exit(1);
65
-	}
64
+        exit(1);
65
+    }
66 66
 
67
-	echo "terminated\n";
67
+    echo "terminated\n";
68 68
 
69 69
 /*
70 70
  * grommunio-sync-top
71 71
  */
72 72
 class GSyncTop {
73
-	// show options
74
-	public const SHOW_DEFAULT = 0;
75
-	public const SHOW_ACTIVE_ONLY = 1;
76
-	public const SHOW_UNKNOWN_ONLY = 2;
77
-	public const SHOW_TERM_DEFAULT_TIME = 5; // 5 secs
78
-
79
-	private $topCollector;
80
-	private $starttime;
81
-	private $action;
82
-	private $filter;
83
-	private $status;
84
-	private $statusexpire;
85
-	private $wide;
86
-	private $wasEnabled;
87
-	private $terminate;
88
-	private $scrSize;
89
-	private $pingInterval;
90
-	private $showPush;
91
-	private $showTermSec;
92
-
93
-	private $linesActive = [];
94
-	private $linesOpen = [];
95
-	private $linesUnknown = [];
96
-	private $linesTerm = [];
97
-	private $pushConn = 0;
98
-	private $activeConn = [];
99
-	private $activeHosts = [];
100
-	private $activeUsers = [];
101
-	private $activeDevices = [];
102
-
103
-	/**
104
-	 * Constructor.
105
-	 */
106
-	public function __construct() {
107
-		$this->starttime = time();
108
-		$this->currenttime = time();
109
-		$this->action = "";
110
-		$this->filter = false;
111
-		$this->status = false;
112
-		$this->statusexpire = 0;
113
-		$this->helpexpire = 0;
114
-		$this->doingTail = false;
115
-		$this->wide = false;
116
-		$this->terminate = false;
117
-		$this->showPush = true;
118
-		$this->showOption = self::SHOW_DEFAULT;
119
-		$this->showTermSec = self::SHOW_TERM_DEFAULT_TIME;
120
-		$this->scrSize = ['width' => 80, 'height' => 24];
121
-		$this->pingInterval = (defined('PING_INTERVAL') && PING_INTERVAL > 0) ? PING_INTERVAL : 12;
122
-
123
-		// get a TopCollector
124
-		$this->topCollector = new TopCollector();
125
-	}
126
-
127
-	/**
128
-	 * Requests data from the running grommunio-sync processes.
129
-	 *
130
-	 * @return
131
-	 */
132
-	private function initialize() {
133
-		// request feedback from active processes
134
-		$this->wasEnabled = $this->topCollector->CollectData();
135
-
136
-		// remove obsolete data
137
-		$this->topCollector->ClearLatest(true);
138
-
139
-		// start with default colours
140
-		$this->scrDefaultColors();
141
-	}
142
-
143
-	/**
144
-	 * Main loop of grommunio-sync-top
145
-	 * Runs until termination is requested.
146
-	 *
147
-	 * @return
148
-	 */
149
-	public function run() {
150
-		$this->initialize();
151
-
152
-		do {
153
-			$this->currenttime = time();
154
-
155
-			// see if shared memory is active
156
-			if (!$this->IsAvailable()) {
157
-				$this->terminate = true;
158
-			}
159
-
160
-			// active processes should continue sending data
161
-			$this->topCollector->CollectData();
162
-
163
-			// get and process data from processes
164
-			$this->topCollector->ClearLatest();
165
-			$topdata = $this->topCollector->ReadLatest();
166
-			$this->processData($topdata);
167
-
168
-			// clear screen
169
-			$this->scrClear();
170
-
171
-			// check if screen size changed
172
-			$s = $this->scrGetSize();
173
-			if ($this->scrSize['width'] != $s['width']) {
174
-				if ($s['width'] > 180) {
175
-					$this->wide = true;
176
-				}
177
-				else {
178
-					$this->wide = false;
179
-				}
180
-			}
181
-			$this->scrSize = $s;
182
-
183
-			// print overview
184
-			$this->scrOverview();
185
-
186
-			// wait for user input
187
-			$this->readLineProcess();
188
-		}
189
-		while ($this->terminate != true);
190
-	}
191
-
192
-	/**
193
-	 * Indicates if TopCollector is available collecting data.
194
-	 *
195
-	 * @return bool
196
-	 */
197
-	public function IsAvailable() {
198
-		if (defined('TOPCOLLECTOR_DISABLED') && constant('TOPCOLLECTOR_DISABLED') === true) {
199
-			return false;
200
-		}
201
-
202
-		return $this->topCollector->IsActive();
203
-	}
204
-
205
-	/**
206
-	 * Processes data written by the running processes.
207
-	 *
208
-	 * @param array $data
209
-	 *
210
-	 * @return
211
-	 */
212
-	private function processData($data) {
213
-		$this->linesActive = [];
214
-		$this->linesOpen = [];
215
-		$this->linesUnknown = [];
216
-		$this->linesTerm = [];
217
-		$this->pushConn = 0;
218
-		$this->activeConn = [];
219
-		$this->activeHosts = [];
220
-		$this->activeUsers = [];
221
-		$this->activeDevices = [];
222
-
223
-		if (!is_array($data)) {
224
-			return;
225
-		}
226
-
227
-		foreach ($data as $devid => $users) {
228
-			foreach ($users as $user => $pids) {
229
-				foreach ($pids as $pid => $line) {
230
-					if (!is_array($line)) {
231
-						continue;
232
-					}
233
-
234
-					$line['command'] = Utils::GetCommandFromCode($line['command']);
235
-
236
-					if ($line["ended"] == 0) {
237
-						$this->activeDevices[$devid] = 1;
238
-						$this->activeUsers[$user] = 1;
239
-						$this->activeConn[$pid] = 1;
240
-						$this->activeHosts[$line['ip']] = 1;
241
-
242
-						$line["time"] = $this->currenttime - $line['start'];
243
-						if ($line['push'] === true) {
244
-							++$this->pushConn;
245
-						}
246
-
247
-						// ignore push connections
248
-						if ($line['push'] === true && !$this->showPush) {
249
-							continue;
250
-						}
251
-
252
-						if ($this->filter !== false) {
253
-							$f = $this->filter;
254
-							if (!($line["pid"] == $f || $line["ip"] == $f || strtolower($line['command']) == strtolower($f) || preg_match("/.*?{$f}.*?/i", $line['user']) ||
255
-								preg_match("/.*?{$f}.*?/i", $line['devagent']) || preg_match("/.*?{$f}.*?/i", $line['devid']) || preg_match("/.*?{$f}.*?/i", $line['addinfo']))) {
256
-								continue;
257
-							}
258
-						}
259
-
260
-						$lastUpdate = $this->currenttime - $line["update"];
261
-						if ($this->currenttime - $line["update"] < 2) {
262
-							$this->linesActive[$line["update"] . $line["pid"]] = $line;
263
-						}
264
-						elseif (($line['push'] === true && $lastUpdate > ($this->pingInterval + 2)) || ($line['push'] !== true && $lastUpdate > 4)) {
265
-							$this->linesUnknown[$line["update"] . $line["pid"]] = $line;
266
-						}
267
-						else {
268
-							$this->linesOpen[$line["update"] . $line["pid"]] = $line;
269
-						}
270
-					}
271
-					else {
272
-						// do not show terminated + expired connections
273
-						if ($this->currenttime > $line['ended'] + $this->showTermSec) {
274
-							continue;
275
-						}
276
-
277
-						if ($this->filter !== false) {
278
-							$f = $this->filter;
279
-							if (
280
-									!(
281
-										$line['pid'] == $f ||
282
-										$line['ip'] == $f ||
283
-										strtolower($line['command']) == strtolower($f) ||
284
-										preg_match("/.*?{$f}.*?/i", $line['user']) ||
285
-										preg_match("/.*?{$f}.*?/i", $line['devagent']) ||
286
-										preg_match("/.*?{$f}.*?/i", $line['devid']) ||
287
-										preg_match("/.*?{$f}.*?/i", $line['addinfo'])
288
-									)) {
289
-								continue;
290
-							}
291
-						}
292
-
293
-						$line['time'] = $line['ended'] - $line['start'];
294
-						$this->linesTerm[$line['update'] . $line['pid']] = $line;
295
-					}
296
-				}
297
-			}
298
-		}
299
-
300
-		// sort by execution time
301
-		krsort($this->linesActive);
302
-		krsort($this->linesOpen);
303
-		krsort($this->linesUnknown);
304
-		krsort($this->linesTerm);
305
-	}
306
-
307
-	/**
308
-	 * Prints data to the terminal.
309
-	 *
310
-	 * @return
311
-	 */
312
-	private function scrOverview() {
313
-		$linesAvail = $this->scrSize['height'] - 8;
314
-		$lc = 1;
315
-		$this->scrPrintAt($lc, 0, "\033[1mgrommunio-sync-top live statistics\033[0m\t\t\t\t\t" . @strftime("%d/%m/%Y %T") . "\n");
316
-		++$lc;
317
-
318
-		$this->scrPrintAt($lc, 0, sprintf("Open connections: %d\t\t\t\tUsers:\t %d\tgrommunio-sync:   %s ", count($this->activeConn), count($this->activeUsers), $this->getVersion()));
319
-		++$lc;
320
-		$this->scrPrintAt($lc, 0, sprintf("Push connections: %d\t\t\t\tDevices: %d\tPHP-MAPI: %s", $this->pushConn, count($this->activeDevices), phpversion("mapi")));
321
-		++$lc;
322
-		$this->scrPrintAt($lc, 0, sprintf("                                                Hosts:\t %d", count($this->activeHosts)));
323
-		++$lc;
324
-		++$lc;
325
-
326
-		$this->scrPrintAt($lc, 0, "\033[4m" . $this->getLine(['pid' => 'PID', 'ip' => 'IP', 'user' => 'USER', 'command' => 'COMMAND', 'time' => 'TIME', 'devagent' => 'AGENT', 'devid' => 'DEVID', 'addinfo' => 'Additional Information']) . str_repeat(" ", 20) . "\033[0m");
327
-		++$lc;
328
-
329
-		// print help text if requested
330
-		$hl = 0;
331
-		if ($this->helpexpire > $this->currenttime) {
332
-			$help = $this->scrHelp();
333
-			$linesAvail -= count($help);
334
-			$hl = $this->scrSize['height'] - count($help) - 1;
335
-			foreach ($help as $h) {
336
-				$this->scrPrintAt($hl, 0, $h);
337
-				++$hl;
338
-			}
339
-		}
340
-
341
-		$toPrintActive = $linesAvail;
342
-		$toPrintOpen = $linesAvail;
343
-		$toPrintUnknown = $linesAvail;
344
-		$toPrintTerm = $linesAvail;
345
-
346
-		// default view: show all unknown, no terminated and half active+open
347
-		if (count($this->linesActive) + count($this->linesOpen) + count($this->linesUnknown) > $linesAvail) {
348
-			$toPrintUnknown = count($this->linesUnknown);
349
-			$toPrintActive = count($this->linesActive);
350
-			$toPrintOpen = $linesAvail - $toPrintUnknown - $toPrintActive;
351
-			$toPrintTerm = 0;
352
-		}
353
-
354
-		if ($this->showOption == self::SHOW_ACTIVE_ONLY) {
355
-			$toPrintActive = $linesAvail;
356
-			$toPrintOpen = 0;
357
-			$toPrintUnknown = 0;
358
-			$toPrintTerm = 0;
359
-		}
360
-
361
-		if ($this->showOption == self::SHOW_UNKNOWN_ONLY) {
362
-			$toPrintActive = 0;
363
-			$toPrintOpen = 0;
364
-			$toPrintUnknown = $linesAvail;
365
-			$toPrintTerm = 0;
366
-		}
367
-
368
-		$linesprinted = 0;
369
-		foreach ($this->linesActive as $time => $l) {
370
-			if ($linesprinted >= $toPrintActive) {
371
-				break;
372
-			}
373
-
374
-			$this->scrPrintAt($lc, 0, "\033[01m" . $this->getLine($l) . "\033[0m");
375
-			++$lc;
376
-			++$linesprinted;
377
-		}
378
-
379
-		$linesprinted = 0;
380
-		foreach ($this->linesOpen as $time => $l) {
381
-			if ($linesprinted >= $toPrintOpen) {
382
-				break;
383
-			}
384
-
385
-			$this->scrPrintAt($lc, 0, $this->getLine($l));
386
-			++$lc;
387
-			++$linesprinted;
388
-		}
389
-
390
-		$linesprinted = 0;
391
-		foreach ($this->linesUnknown as $time => $l) {
392
-			if ($linesprinted >= $toPrintUnknown) {
393
-				break;
394
-			}
395
-
396
-			$color = "0;31m";
397
-			if ($l['push'] == false && $time - $l["start"] > 30) {
398
-				$color = "1;31m";
399
-			}
400
-			$this->scrPrintAt($lc, 0, "\033[0" . $color . $this->getLine($l) . "\033[0m");
401
-			++$lc;
402
-			++$linesprinted;
403
-		}
404
-
405
-		if ($toPrintTerm > 0) {
406
-			$toPrintTerm = $linesAvail - $lc + 6;
407
-		}
408
-
409
-		$linesprinted = 0;
410
-		foreach ($this->linesTerm as $time => $l) {
411
-			if ($linesprinted >= $toPrintTerm) {
412
-				break;
413
-			}
414
-
415
-			$this->scrPrintAt($lc, 0, "\033[01;30m" . $this->getLine($l) . "\033[0m");
416
-			++$lc;
417
-			++$linesprinted;
418
-		}
419
-
420
-		// add the lines used when displaying the help text
421
-		$lc += $hl;
422
-		$this->scrPrintAt($lc, 0, "\033[K");
423
-		++$lc;
424
-		$this->scrPrintAt($lc, 0, "Colorscheme: \033[01mActive  \033[0mOpen  \033[01;31mUnknown  \033[01;30mTerminated\033[0m");
425
-
426
-		// remove old status
427
-		if ($this->statusexpire < $this->currenttime) {
428
-			$this->status = false;
429
-		}
430
-
431
-		// show request information and help command
432
-		if ($this->starttime + 6 > $this->currenttime) {
433
-			$this->status = sprintf("Requesting information (takes up to %dsecs)", $this->pingInterval) . str_repeat(".", ($this->currenttime - $this->starttime)) . "  type \033[01;31mh\033[00;31m or \033[01;31mhelp\033[00;31m for usage instructions";
434
-			$this->statusexpire = $this->currenttime + 1;
435
-		}
436
-
437
-		$str = "";
438
-		if (!$this->showPush) {
439
-			$str .= "\033[00;32mPush: \033[01;32mNo\033[0m   ";
440
-		}
441
-
442
-		if ($this->showOption == self::SHOW_ACTIVE_ONLY) {
443
-			$str .= "\033[01;32mActive only\033[0m   ";
444
-		}
445
-
446
-		if ($this->showOption == self::SHOW_UNKNOWN_ONLY) {
447
-			$str .= "\033[01;32mUnknown only\033[0m   ";
448
-		}
449
-
450
-		if ($this->showTermSec != self::SHOW_TERM_DEFAULT_TIME) {
451
-			$str .= "\033[01;32mTerminated: " . $this->showTermSec . "s\033[0m   ";
452
-		}
453
-
454
-		if ($this->filter !== false || ($this->status !== false && $this->statusexpire > $this->currenttime)) {
455
-			// print filter in green
456
-			if ($this->filter !== false) {
457
-				$str .= "\033[00;32mFilter: \033[01;32m{$this->filter}\033[0m   ";
458
-			}
459
-			// print status in red
460
-			if ($this->status !== false) {
461
-				$str .= "\033[00;31m{$this->status}\033[0m";
462
-			}
463
-		}
464
-		$this->scrPrintAt(5, 0, $str);
465
-
466
-		$this->scrPrintAt(4, 0, "Action: \033[01m" . $this->action . "\033[0m");
467
-	}
468
-
469
-	/**
470
-	 * Waits for a keystroke and processes the requested command.
471
-	 *
472
-	 * @return
473
-	 */
474
-	private function readLineProcess() {
475
-		$ans = explode("^^", `bash -c "read -n 1 -t 1 ANS ; echo \\\$?^^\\\$ANS;"`);
476
-
477
-		if ($ans[0] < 128) {
478
-			if (isset($ans[1]) && bin2hex(trim($ans[1])) == "7f") {
479
-				$this->action = substr($this->action, 0, -1);
480
-			}
481
-
482
-			if (isset($ans[1]) && $ans[1] != "") {
483
-				$this->action .= trim(preg_replace("/[^A-Za-z0-9:]/", "", $ans[1]));
484
-			}
485
-
486
-			if (bin2hex($ans[0]) == "30" && bin2hex($ans[1]) == "0a") {
487
-				$cmds = explode(':', $this->action);
488
-				if ($cmds[0] == "quit" || $cmds[0] == "q" || (isset($cmds[1]) && $cmds[0] == "" && $cmds[1] == "q")) {
489
-					$this->topCollector->CollectData(true);
490
-					$this->topCollector->ClearLatest(true);
491
-
492
-					$this->terminate = true;
493
-				}
494
-				elseif ($cmds[0] == "clear") {
495
-					$this->topCollector->ClearLatest(true);
496
-					$this->topCollector->CollectData(true);
497
-					$this->topCollector->ReInitIPC();
498
-				}
499
-				elseif ($cmds[0] == "filter" || $cmds[0] == "f") {
500
-					if (!isset($cmds[1]) || $cmds[1] == "") {
501
-						$this->filter = false;
502
-						$this->status = "No filter";
503
-						$this->statusexpire = $this->currenttime + 5;
504
-					}
505
-					else {
506
-						$this->filter = $cmds[1];
507
-						$this->status = false;
508
-					}
509
-				}
510
-				elseif ($cmds[0] == "option" || $cmds[0] == "o") {
511
-					if (!isset($cmds[1]) || $cmds[1] == "") {
512
-						$this->status = "Option value needs to be specified. See 'help' or 'h' for instructions";
513
-						$this->statusexpire = $this->currenttime + 5;
514
-					}
515
-					elseif ($cmds[1] == "p" || $cmds[1] == "push" || $cmds[1] == "ping") {
516
-						$this->showPush = !$this->showPush;
517
-					}
518
-					elseif ($cmds[1] == "a" || $cmds[1] == "active") {
519
-						$this->showOption = self::SHOW_ACTIVE_ONLY;
520
-					}
521
-					elseif ($cmds[1] == "u" || $cmds[1] == "unknown") {
522
-						$this->showOption = self::SHOW_UNKNOWN_ONLY;
523
-					}
524
-					elseif ($cmds[1] == "d" || $cmds[1] == "default") {
525
-						$this->showOption = self::SHOW_DEFAULT;
526
-						$this->showTermSec = self::SHOW_TERM_DEFAULT_TIME;
527
-						$this->showPush = true;
528
-					}
529
-					elseif (is_numeric($cmds[1])) {
530
-						$this->showTermSec = $cmds[1];
531
-					}
532
-					else {
533
-						$this->status = sprintf("Option '%s' unknown", $cmds[1]);
534
-						$this->statusexpire = $this->currenttime + 5;
535
-					}
536
-				}
537
-				elseif ($cmds[0] == "reset" || $cmds[0] == "r") {
538
-					$this->filter = false;
539
-					$this->wide = false;
540
-					$this->helpexpire = 0;
541
-					$this->status = "reset";
542
-					$this->statusexpire = $this->currenttime + 2;
543
-				}
544
-				// enable/disable wide view
545
-				elseif ($cmds[0] == "wide" || $cmds[0] == "w") {
546
-					$this->wide = !$this->wide;
547
-					$this->status = ($this->wide) ? "w i d e  view" : "normal view";
548
-					$this->statusexpire = $this->currenttime + 2;
549
-				}
550
-				elseif ($cmds[0] == "help" || $cmds[0] == "h") {
551
-					$this->helpexpire = $this->currenttime + 20;
552
-				}
553
-				// grep the log file
554
-				elseif (($cmds[0] == "log" || $cmds[0] == "l") && isset($cmds[1])) {
555
-					if (!file_exists(LOGFILE)) {
556
-						$this->status = "Logfile can not be found: " . LOGFILE;
557
-					}
558
-					else {
559
-						system('bash -c "fgrep -a ' . escapeshellarg($cmds[1]) . ' ' . LOGFILE . ' | less +G" > `tty`');
560
-						$this->status = "Returning from log, updating data";
561
-					}
562
-					$this->statusexpire = time() + 5; // it might be much "later" now
563
-				}
564
-				// tail the log file
565
-				elseif (($cmds[0] == "tail" || $cmds[0] == "t")) {
566
-					if (!file_exists(LOGFILE)) {
567
-						$this->status = "Logfile can not be found: " . LOGFILE;
568
-					}
569
-					else {
570
-						$this->doingTail = true;
571
-						$this->scrClear();
572
-						$this->scrPrintAt(1, 0, $this->scrAsBold("Press CTRL+C to return to grommunio-sync-top\n\n"));
573
-						$secondary = "";
574
-						if (isset($cmds[1])) {
575
-							$secondary = " -n 200 | grep " . escapeshellarg($cmds[1]);
576
-						}
577
-						system('bash -c "tail -f ' . LOGFILE . $secondary . '" > `tty`');
578
-						$this->doingTail = false;
579
-						$this->status = "Returning from tail, updating data";
580
-					}
581
-					$this->statusexpire = time() + 5; // it might be much "later" now
582
-				}
583
-				// tail the error log file
584
-				elseif (($cmds[0] == "error" || $cmds[0] == "e")) {
585
-					if (!file_exists(LOGERRORFILE)) {
586
-						$this->status = "Error logfile can not be found: " . LOGERRORFILE;
587
-					}
588
-					else {
589
-						$this->doingTail = true;
590
-						$this->scrClear();
591
-						$this->scrPrintAt(1, 0, $this->scrAsBold("Press CTRL+C to return to grommunio-sync-top\n\n"));
592
-						$secondary = "";
593
-						if (isset($cmds[1])) {
594
-							$secondary = " -n 200 | grep " . escapeshellarg($cmds[1]);
595
-						}
596
-						system('bash -c "tail -f ' . LOGERRORFILE . $secondary . '" > `tty`');
597
-						$this->doingTail = false;
598
-						$this->status = "Returning from tail, updating data";
599
-					}
600
-					$this->statusexpire = time() + 5; // it might be much "later" now
601
-				}
602
-				elseif ($cmds[0] != "") {
603
-					$this->status = sprintf("Command '%s' unknown", $cmds[0]);
604
-					$this->statusexpire = $this->currenttime + 8;
605
-				}
606
-				$this->action = "";
607
-			}
608
-		}
609
-	}
610
-
611
-	/**
612
-	 * Signal handler function.
613
-	 *
614
-	 * @param int $signo signal number
615
-	 *
616
-	 * @return
617
-	 */
618
-	public function SignalHandler($signo) {
619
-		// don't terminate if the signal was sent by terminating tail
620
-		if (!$this->doingTail) {
621
-			$this->topCollector->CollectData(true);
622
-			$this->topCollector->ClearLatest(true);
623
-			$this->terminate = true;
624
-		}
625
-	}
626
-
627
-	/**
628
-	 * Returns usage instructions.
629
-	 *
630
-	 * @return string
631
-	 */
632
-	public function UsageInstructions() {
633
-		$help = "Usage:\n\tgrommunio-sync-top.php\n\n" .
634
-				"  grommunio-sync-top is a live top-like overview of what grommunio-sync is doing. It does not have specific command line options.\n\n" .
635
-				"  When grommunio-sync-top is running you can specify certain actions and options which can be executed (listed below).\n" .
636
-				"  This help information can also be shown inside grommunio-sync-top by hitting 'help' or 'h'.\n\n";
637
-		$scrhelp = $this->scrHelp();
638
-		unset($scrhelp[0]);
639
-
640
-		$help .= implode("\n", $scrhelp);
641
-		$help .= "\n\n";
642
-
643
-		return $help;
644
-	}
645
-
646
-	/**
647
-	 * Prints a 'help' text at the end of the page.
648
-	 *
649
-	 * @return array with help lines
650
-	 */
651
-	private function scrHelp() {
652
-		$h = [];
653
-		$secs = $this->helpexpire - $this->currenttime;
654
-		$h[] = "Actions supported by grommunio-sync-top (help page still displayed for " . $secs . "secs)";
655
-		$h[] = "  " . $this->scrAsBold("Action") . "\t\t" . $this->scrAsBold("Comment");
656
-		$h[] = "  " . $this->scrAsBold("h") . " or " . $this->scrAsBold("help") . "\t\tDisplays this information.";
657
-		$h[] = "  " . $this->scrAsBold("q") . ", " . $this->scrAsBold("quit") . " or " . $this->scrAsBold(":q") . "\t\tExits grommunio-sync-top.";
658
-		$h[] = "  " . $this->scrAsBold("w") . " or " . $this->scrAsBold("wide") . "\t\tTries not to truncate data. Automatically done if more than 180 columns available.";
659
-		$h[] = "  " . $this->scrAsBold("f:VAL") . " or " . $this->scrAsBold("filter:VAL") . "\tOnly display connections which contain VAL. This value is case-insensitive.";
660
-		$h[] = "  " . $this->scrAsBold("f:") . " or " . $this->scrAsBold("filter:") . "\t\tWithout a search word: resets the filter.";
661
-		$h[] = "  " . $this->scrAsBold("l:STR") . " or " . $this->scrAsBold("log:STR") . "\tIssues 'less +G' on the logfile, after grepping on the optional STR.";
662
-		$h[] = "  " . $this->scrAsBold("t:STR") . " or " . $this->scrAsBold("tail:STR") . "\tIssues 'tail -f' on the logfile, grepping for optional STR.";
663
-		$h[] = "  " . $this->scrAsBold("e:STR") . " or " . $this->scrAsBold("error:STR") . "\tIssues 'tail -f' on the error logfile, grepping for optional STR.";
664
-		$h[] = "  " . $this->scrAsBold("r") . " or " . $this->scrAsBold("reset") . "\t\tResets 'wide' or 'filter'.";
665
-		$h[] = "  " . $this->scrAsBold("o:") . " or " . $this->scrAsBold("option:") . "\t\tSets display options. Valid options specified below";
666
-		$h[] = "  " . $this->scrAsBold("  p") . " or " . $this->scrAsBold("push") . "\t\tLists/not lists active and open push connections.";
667
-		$h[] = "  " . $this->scrAsBold("  a") . " or " . $this->scrAsBold("action") . "\t\tLists only active connections.";
668
-		$h[] = "  " . $this->scrAsBold("  u") . " or " . $this->scrAsBold("unknown") . "\tLists only unknown connections.";
669
-		$h[] = "  " . $this->scrAsBold("  10") . " or " . $this->scrAsBold("20") . "\t\tLists terminated connections for 10 or 20 seconds. Any other number can be used.";
670
-		$h[] = "  " . $this->scrAsBold("  d") . " or " . $this->scrAsBold("default") . "\tUses default options";
671
-
672
-		return $h;
673
-	}
674
-
675
-	/**
676
-	 * Encapsulates string with different color escape characters.
677
-	 *
678
-	 * @param string $text
679
-	 *
680
-	 * @return string same text as bold
681
-	 */
682
-	private function scrAsBold($text) {
683
-		return "\033[01m" . $text . "\033[0m";
684
-	}
685
-
686
-	/**
687
-	 * Prints one line of precessed data.
688
-	 *
689
-	 * @param array $l line information
690
-	 *
691
-	 * @return string
692
-	 */
693
-	private function getLine($l) {
694
-		if ($this->wide === true) {
695
-			return sprintf("%s%s%s%s%s%s%s%s", $this->ptStr($l['pid'], 6), $this->ptStr($l['ip'], 16), $this->ptStr($l['user'], 24), $this->ptStr($l['command'], 16), $this->ptStr($this->sec2min($l['time']), 8), $this->ptStr($l['devagent'], 28), $this->ptStr($l['devid'], 33, true), $l['addinfo']);
696
-		}
697
-
698
-		return sprintf("%s%s%s%s%s%s%s%s", $this->ptStr($l['pid'], 6), $this->ptStr($l['ip'], 16), $this->ptStr($l['user'], 8), $this->ptStr($l['command'], 8), $this->ptStr($this->sec2min($l['time']), 6), $this->ptStr($l['devagent'], 20), $this->ptStr($l['devid'], 12, true), $l['addinfo']);
699
-	}
700
-
701
-	/**
702
-	 * Pads and trims string.
703
-	 *
704
-	 * @param string $str       to be trimmed/padded
705
-	 * @param int    $size      characters to be considered
706
-	 * @param bool   $cutmiddle (optional) indicates where to long information should
707
-	 *                          be trimmed of, false means at the end
708
-	 *
709
-	 * @return string
710
-	 */
711
-	private function ptStr($str, $size, $cutmiddle = false) {
712
-		if (strlen($str) < $size) {
713
-			return str_pad($str, $size);
714
-		}
715
-		if ($cutmiddle == true) {
716
-			$cut = ($size - 2) / 2;
717
-
718
-			return $this->ptStr(substr($str, 0, $cut) . ".." . substr($str, (-1) * ($cut - 1)), $size);
719
-		}
720
-
721
-		return substr($str, 0, $size - 3) . ".. ";
722
-	}
723
-
724
-	/**
725
-	 * Tries to discover the size of the current terminal.
726
-	 *
727
-	 * @return array 'width' and 'height' as keys
728
-	 */
729
-	private function scrGetSize() {
730
-		$tty = strtolower(exec('stty -a | fgrep columns'));
731
-		if (preg_match_all("/rows.([0-9]+);.columns.([0-9]+);/", $tty, $output) ||
732
-			preg_match_all("/([0-9]+).rows;.([0-9]+).columns;/", $tty, $output)) {
733
-			return ['width' => $output[2][0], 'height' => $output[1][0]];
734
-		}
735
-
736
-		return ['width' => 80, 'height' => 24];
737
-	}
738
-
739
-	/**
740
-	 * Returns the version of the current grommunio-sync installation.
741
-	 *
742
-	 * @return string
743
-	 */
744
-	private function getVersion() {
745
-		return GROMMUNIOSYNC_VERSION;
746
-	}
747
-
748
-	/**
749
-	 * Converts seconds in MM:SS.
750
-	 *
751
-	 * @param int $s seconds
752
-	 *
753
-	 * @return string
754
-	 */
755
-	private function sec2min($s) {
756
-		if (!is_int($s)) {
757
-			return $s;
758
-		}
759
-
760
-		return sprintf("%02.2d:%02.2d", floor($s / 60), $s % 60);
761
-	}
762
-
763
-	/**
764
-	 * Resets the default colors of the terminal.
765
-	 *
766
-	 * @return
767
-	 */
768
-	private function scrDefaultColors() {
769
-		echo "\033[0m";
770
-	}
771
-
772
-	/**
773
-	 * Clears screen of the terminal.
774
-	 *
775
-	 * @param array $data
776
-	 *
777
-	 * @return
778
-	 */
779
-	public function scrClear() {
780
-		echo "\033[2J";
781
-	}
782
-
783
-	/**
784
-	 * Prints a text at a specific screen/terminal coordinates.
785
-	 *
786
-	 * @param int    $row  row number
787
-	 * @param int    $col  column number
788
-	 * @param string $text to be printed
789
-	 *
790
-	 * @return
791
-	 */
792
-	private function scrPrintAt($row, $col, $text = "") {
793
-		echo "\033[" . $row . ";" . $col . "H" . $text;
794
-	}
73
+    // show options
74
+    public const SHOW_DEFAULT = 0;
75
+    public const SHOW_ACTIVE_ONLY = 1;
76
+    public const SHOW_UNKNOWN_ONLY = 2;
77
+    public const SHOW_TERM_DEFAULT_TIME = 5; // 5 secs
78
+
79
+    private $topCollector;
80
+    private $starttime;
81
+    private $action;
82
+    private $filter;
83
+    private $status;
84
+    private $statusexpire;
85
+    private $wide;
86
+    private $wasEnabled;
87
+    private $terminate;
88
+    private $scrSize;
89
+    private $pingInterval;
90
+    private $showPush;
91
+    private $showTermSec;
92
+
93
+    private $linesActive = [];
94
+    private $linesOpen = [];
95
+    private $linesUnknown = [];
96
+    private $linesTerm = [];
97
+    private $pushConn = 0;
98
+    private $activeConn = [];
99
+    private $activeHosts = [];
100
+    private $activeUsers = [];
101
+    private $activeDevices = [];
102
+
103
+    /**
104
+     * Constructor.
105
+     */
106
+    public function __construct() {
107
+        $this->starttime = time();
108
+        $this->currenttime = time();
109
+        $this->action = "";
110
+        $this->filter = false;
111
+        $this->status = false;
112
+        $this->statusexpire = 0;
113
+        $this->helpexpire = 0;
114
+        $this->doingTail = false;
115
+        $this->wide = false;
116
+        $this->terminate = false;
117
+        $this->showPush = true;
118
+        $this->showOption = self::SHOW_DEFAULT;
119
+        $this->showTermSec = self::SHOW_TERM_DEFAULT_TIME;
120
+        $this->scrSize = ['width' => 80, 'height' => 24];
121
+        $this->pingInterval = (defined('PING_INTERVAL') && PING_INTERVAL > 0) ? PING_INTERVAL : 12;
122
+
123
+        // get a TopCollector
124
+        $this->topCollector = new TopCollector();
125
+    }
126
+
127
+    /**
128
+     * Requests data from the running grommunio-sync processes.
129
+     *
130
+     * @return
131
+     */
132
+    private function initialize() {
133
+        // request feedback from active processes
134
+        $this->wasEnabled = $this->topCollector->CollectData();
135
+
136
+        // remove obsolete data
137
+        $this->topCollector->ClearLatest(true);
138
+
139
+        // start with default colours
140
+        $this->scrDefaultColors();
141
+    }
142
+
143
+    /**
144
+     * Main loop of grommunio-sync-top
145
+     * Runs until termination is requested.
146
+     *
147
+     * @return
148
+     */
149
+    public function run() {
150
+        $this->initialize();
151
+
152
+        do {
153
+            $this->currenttime = time();
154
+
155
+            // see if shared memory is active
156
+            if (!$this->IsAvailable()) {
157
+                $this->terminate = true;
158
+            }
159
+
160
+            // active processes should continue sending data
161
+            $this->topCollector->CollectData();
162
+
163
+            // get and process data from processes
164
+            $this->topCollector->ClearLatest();
165
+            $topdata = $this->topCollector->ReadLatest();
166
+            $this->processData($topdata);
167
+
168
+            // clear screen
169
+            $this->scrClear();
170
+
171
+            // check if screen size changed
172
+            $s = $this->scrGetSize();
173
+            if ($this->scrSize['width'] != $s['width']) {
174
+                if ($s['width'] > 180) {
175
+                    $this->wide = true;
176
+                }
177
+                else {
178
+                    $this->wide = false;
179
+                }
180
+            }
181
+            $this->scrSize = $s;
182
+
183
+            // print overview
184
+            $this->scrOverview();
185
+
186
+            // wait for user input
187
+            $this->readLineProcess();
188
+        }
189
+        while ($this->terminate != true);
190
+    }
191
+
192
+    /**
193
+     * Indicates if TopCollector is available collecting data.
194
+     *
195
+     * @return bool
196
+     */
197
+    public function IsAvailable() {
198
+        if (defined('TOPCOLLECTOR_DISABLED') && constant('TOPCOLLECTOR_DISABLED') === true) {
199
+            return false;
200
+        }
201
+
202
+        return $this->topCollector->IsActive();
203
+    }
204
+
205
+    /**
206
+     * Processes data written by the running processes.
207
+     *
208
+     * @param array $data
209
+     *
210
+     * @return
211
+     */
212
+    private function processData($data) {
213
+        $this->linesActive = [];
214
+        $this->linesOpen = [];
215
+        $this->linesUnknown = [];
216
+        $this->linesTerm = [];
217
+        $this->pushConn = 0;
218
+        $this->activeConn = [];
219
+        $this->activeHosts = [];
220
+        $this->activeUsers = [];
221
+        $this->activeDevices = [];
222
+
223
+        if (!is_array($data)) {
224
+            return;
225
+        }
226
+
227
+        foreach ($data as $devid => $users) {
228
+            foreach ($users as $user => $pids) {
229
+                foreach ($pids as $pid => $line) {
230
+                    if (!is_array($line)) {
231
+                        continue;
232
+                    }
233
+
234
+                    $line['command'] = Utils::GetCommandFromCode($line['command']);
235
+
236
+                    if ($line["ended"] == 0) {
237
+                        $this->activeDevices[$devid] = 1;
238
+                        $this->activeUsers[$user] = 1;
239
+                        $this->activeConn[$pid] = 1;
240
+                        $this->activeHosts[$line['ip']] = 1;
241
+
242
+                        $line["time"] = $this->currenttime - $line['start'];
243
+                        if ($line['push'] === true) {
244
+                            ++$this->pushConn;
245
+                        }
246
+
247
+                        // ignore push connections
248
+                        if ($line['push'] === true && !$this->showPush) {
249
+                            continue;
250
+                        }
251
+
252
+                        if ($this->filter !== false) {
253
+                            $f = $this->filter;
254
+                            if (!($line["pid"] == $f || $line["ip"] == $f || strtolower($line['command']) == strtolower($f) || preg_match("/.*?{$f}.*?/i", $line['user']) ||
255
+                                preg_match("/.*?{$f}.*?/i", $line['devagent']) || preg_match("/.*?{$f}.*?/i", $line['devid']) || preg_match("/.*?{$f}.*?/i", $line['addinfo']))) {
256
+                                continue;
257
+                            }
258
+                        }
259
+
260
+                        $lastUpdate = $this->currenttime - $line["update"];
261
+                        if ($this->currenttime - $line["update"] < 2) {
262
+                            $this->linesActive[$line["update"] . $line["pid"]] = $line;
263
+                        }
264
+                        elseif (($line['push'] === true && $lastUpdate > ($this->pingInterval + 2)) || ($line['push'] !== true && $lastUpdate > 4)) {
265
+                            $this->linesUnknown[$line["update"] . $line["pid"]] = $line;
266
+                        }
267
+                        else {
268
+                            $this->linesOpen[$line["update"] . $line["pid"]] = $line;
269
+                        }
270
+                    }
271
+                    else {
272
+                        // do not show terminated + expired connections
273
+                        if ($this->currenttime > $line['ended'] + $this->showTermSec) {
274
+                            continue;
275
+                        }
276
+
277
+                        if ($this->filter !== false) {
278
+                            $f = $this->filter;
279
+                            if (
280
+                                    !(
281
+                                        $line['pid'] == $f ||
282
+                                        $line['ip'] == $f ||
283
+                                        strtolower($line['command']) == strtolower($f) ||
284
+                                        preg_match("/.*?{$f}.*?/i", $line['user']) ||
285
+                                        preg_match("/.*?{$f}.*?/i", $line['devagent']) ||
286
+                                        preg_match("/.*?{$f}.*?/i", $line['devid']) ||
287
+                                        preg_match("/.*?{$f}.*?/i", $line['addinfo'])
288
+                                    )) {
289
+                                continue;
290
+                            }
291
+                        }
292
+
293
+                        $line['time'] = $line['ended'] - $line['start'];
294
+                        $this->linesTerm[$line['update'] . $line['pid']] = $line;
295
+                    }
296
+                }
297
+            }
298
+        }
299
+
300
+        // sort by execution time
301
+        krsort($this->linesActive);
302
+        krsort($this->linesOpen);
303
+        krsort($this->linesUnknown);
304
+        krsort($this->linesTerm);
305
+    }
306
+
307
+    /**
308
+     * Prints data to the terminal.
309
+     *
310
+     * @return
311
+     */
312
+    private function scrOverview() {
313
+        $linesAvail = $this->scrSize['height'] - 8;
314
+        $lc = 1;
315
+        $this->scrPrintAt($lc, 0, "\033[1mgrommunio-sync-top live statistics\033[0m\t\t\t\t\t" . @strftime("%d/%m/%Y %T") . "\n");
316
+        ++$lc;
317
+
318
+        $this->scrPrintAt($lc, 0, sprintf("Open connections: %d\t\t\t\tUsers:\t %d\tgrommunio-sync:   %s ", count($this->activeConn), count($this->activeUsers), $this->getVersion()));
319
+        ++$lc;
320
+        $this->scrPrintAt($lc, 0, sprintf("Push connections: %d\t\t\t\tDevices: %d\tPHP-MAPI: %s", $this->pushConn, count($this->activeDevices), phpversion("mapi")));
321
+        ++$lc;
322
+        $this->scrPrintAt($lc, 0, sprintf("                                                Hosts:\t %d", count($this->activeHosts)));
323
+        ++$lc;
324
+        ++$lc;
325
+
326
+        $this->scrPrintAt($lc, 0, "\033[4m" . $this->getLine(['pid' => 'PID', 'ip' => 'IP', 'user' => 'USER', 'command' => 'COMMAND', 'time' => 'TIME', 'devagent' => 'AGENT', 'devid' => 'DEVID', 'addinfo' => 'Additional Information']) . str_repeat(" ", 20) . "\033[0m");
327
+        ++$lc;
328
+
329
+        // print help text if requested
330
+        $hl = 0;
331
+        if ($this->helpexpire > $this->currenttime) {
332
+            $help = $this->scrHelp();
333
+            $linesAvail -= count($help);
334
+            $hl = $this->scrSize['height'] - count($help) - 1;
335
+            foreach ($help as $h) {
336
+                $this->scrPrintAt($hl, 0, $h);
337
+                ++$hl;
338
+            }
339
+        }
340
+
341
+        $toPrintActive = $linesAvail;
342
+        $toPrintOpen = $linesAvail;
343
+        $toPrintUnknown = $linesAvail;
344
+        $toPrintTerm = $linesAvail;
345
+
346
+        // default view: show all unknown, no terminated and half active+open
347
+        if (count($this->linesActive) + count($this->linesOpen) + count($this->linesUnknown) > $linesAvail) {
348
+            $toPrintUnknown = count($this->linesUnknown);
349
+            $toPrintActive = count($this->linesActive);
350
+            $toPrintOpen = $linesAvail - $toPrintUnknown - $toPrintActive;
351
+            $toPrintTerm = 0;
352
+        }
353
+
354
+        if ($this->showOption == self::SHOW_ACTIVE_ONLY) {
355
+            $toPrintActive = $linesAvail;
356
+            $toPrintOpen = 0;
357
+            $toPrintUnknown = 0;
358
+            $toPrintTerm = 0;
359
+        }
360
+
361
+        if ($this->showOption == self::SHOW_UNKNOWN_ONLY) {
362
+            $toPrintActive = 0;
363
+            $toPrintOpen = 0;
364
+            $toPrintUnknown = $linesAvail;
365
+            $toPrintTerm = 0;
366
+        }
367
+
368
+        $linesprinted = 0;
369
+        foreach ($this->linesActive as $time => $l) {
370
+            if ($linesprinted >= $toPrintActive) {
371
+                break;
372
+            }
373
+
374
+            $this->scrPrintAt($lc, 0, "\033[01m" . $this->getLine($l) . "\033[0m");
375
+            ++$lc;
376
+            ++$linesprinted;
377
+        }
378
+
379
+        $linesprinted = 0;
380
+        foreach ($this->linesOpen as $time => $l) {
381
+            if ($linesprinted >= $toPrintOpen) {
382
+                break;
383
+            }
384
+
385
+            $this->scrPrintAt($lc, 0, $this->getLine($l));
386
+            ++$lc;
387
+            ++$linesprinted;
388
+        }
389
+
390
+        $linesprinted = 0;
391
+        foreach ($this->linesUnknown as $time => $l) {
392
+            if ($linesprinted >= $toPrintUnknown) {
393
+                break;
394
+            }
395
+
396
+            $color = "0;31m";
397
+            if ($l['push'] == false && $time - $l["start"] > 30) {
398
+                $color = "1;31m";
399
+            }
400
+            $this->scrPrintAt($lc, 0, "\033[0" . $color . $this->getLine($l) . "\033[0m");
401
+            ++$lc;
402
+            ++$linesprinted;
403
+        }
404
+
405
+        if ($toPrintTerm > 0) {
406
+            $toPrintTerm = $linesAvail - $lc + 6;
407
+        }
408
+
409
+        $linesprinted = 0;
410
+        foreach ($this->linesTerm as $time => $l) {
411
+            if ($linesprinted >= $toPrintTerm) {
412
+                break;
413
+            }
414
+
415
+            $this->scrPrintAt($lc, 0, "\033[01;30m" . $this->getLine($l) . "\033[0m");
416
+            ++$lc;
417
+            ++$linesprinted;
418
+        }
419
+
420
+        // add the lines used when displaying the help text
421
+        $lc += $hl;
422
+        $this->scrPrintAt($lc, 0, "\033[K");
423
+        ++$lc;
424
+        $this->scrPrintAt($lc, 0, "Colorscheme: \033[01mActive  \033[0mOpen  \033[01;31mUnknown  \033[01;30mTerminated\033[0m");
425
+
426
+        // remove old status
427
+        if ($this->statusexpire < $this->currenttime) {
428
+            $this->status = false;
429
+        }
430
+
431
+        // show request information and help command
432
+        if ($this->starttime + 6 > $this->currenttime) {
433
+            $this->status = sprintf("Requesting information (takes up to %dsecs)", $this->pingInterval) . str_repeat(".", ($this->currenttime - $this->starttime)) . "  type \033[01;31mh\033[00;31m or \033[01;31mhelp\033[00;31m for usage instructions";
434
+            $this->statusexpire = $this->currenttime + 1;
435
+        }
436
+
437
+        $str = "";
438
+        if (!$this->showPush) {
439
+            $str .= "\033[00;32mPush: \033[01;32mNo\033[0m   ";
440
+        }
441
+
442
+        if ($this->showOption == self::SHOW_ACTIVE_ONLY) {
443
+            $str .= "\033[01;32mActive only\033[0m   ";
444
+        }
445
+
446
+        if ($this->showOption == self::SHOW_UNKNOWN_ONLY) {
447
+            $str .= "\033[01;32mUnknown only\033[0m   ";
448
+        }
449
+
450
+        if ($this->showTermSec != self::SHOW_TERM_DEFAULT_TIME) {
451
+            $str .= "\033[01;32mTerminated: " . $this->showTermSec . "s\033[0m   ";
452
+        }
453
+
454
+        if ($this->filter !== false || ($this->status !== false && $this->statusexpire > $this->currenttime)) {
455
+            // print filter in green
456
+            if ($this->filter !== false) {
457
+                $str .= "\033[00;32mFilter: \033[01;32m{$this->filter}\033[0m   ";
458
+            }
459
+            // print status in red
460
+            if ($this->status !== false) {
461
+                $str .= "\033[00;31m{$this->status}\033[0m";
462
+            }
463
+        }
464
+        $this->scrPrintAt(5, 0, $str);
465
+
466
+        $this->scrPrintAt(4, 0, "Action: \033[01m" . $this->action . "\033[0m");
467
+    }
468
+
469
+    /**
470
+     * Waits for a keystroke and processes the requested command.
471
+     *
472
+     * @return
473
+     */
474
+    private function readLineProcess() {
475
+        $ans = explode("^^", `bash -c "read -n 1 -t 1 ANS ; echo \\\$?^^\\\$ANS;"`);
476
+
477
+        if ($ans[0] < 128) {
478
+            if (isset($ans[1]) && bin2hex(trim($ans[1])) == "7f") {
479
+                $this->action = substr($this->action, 0, -1);
480
+            }
481
+
482
+            if (isset($ans[1]) && $ans[1] != "") {
483
+                $this->action .= trim(preg_replace("/[^A-Za-z0-9:]/", "", $ans[1]));
484
+            }
485
+
486
+            if (bin2hex($ans[0]) == "30" && bin2hex($ans[1]) == "0a") {
487
+                $cmds = explode(':', $this->action);
488
+                if ($cmds[0] == "quit" || $cmds[0] == "q" || (isset($cmds[1]) && $cmds[0] == "" && $cmds[1] == "q")) {
489
+                    $this->topCollector->CollectData(true);
490
+                    $this->topCollector->ClearLatest(true);
491
+
492
+                    $this->terminate = true;
493
+                }
494
+                elseif ($cmds[0] == "clear") {
495
+                    $this->topCollector->ClearLatest(true);
496
+                    $this->topCollector->CollectData(true);
497
+                    $this->topCollector->ReInitIPC();
498
+                }
499
+                elseif ($cmds[0] == "filter" || $cmds[0] == "f") {
500
+                    if (!isset($cmds[1]) || $cmds[1] == "") {
501
+                        $this->filter = false;
502
+                        $this->status = "No filter";
503
+                        $this->statusexpire = $this->currenttime + 5;
504
+                    }
505
+                    else {
506
+                        $this->filter = $cmds[1];
507
+                        $this->status = false;
508
+                    }
509
+                }
510
+                elseif ($cmds[0] == "option" || $cmds[0] == "o") {
511
+                    if (!isset($cmds[1]) || $cmds[1] == "") {
512
+                        $this->status = "Option value needs to be specified. See 'help' or 'h' for instructions";
513
+                        $this->statusexpire = $this->currenttime + 5;
514
+                    }
515
+                    elseif ($cmds[1] == "p" || $cmds[1] == "push" || $cmds[1] == "ping") {
516
+                        $this->showPush = !$this->showPush;
517
+                    }
518
+                    elseif ($cmds[1] == "a" || $cmds[1] == "active") {
519
+                        $this->showOption = self::SHOW_ACTIVE_ONLY;
520
+                    }
521
+                    elseif ($cmds[1] == "u" || $cmds[1] == "unknown") {
522
+                        $this->showOption = self::SHOW_UNKNOWN_ONLY;
523
+                    }
524
+                    elseif ($cmds[1] == "d" || $cmds[1] == "default") {
525
+                        $this->showOption = self::SHOW_DEFAULT;
526
+                        $this->showTermSec = self::SHOW_TERM_DEFAULT_TIME;
527
+                        $this->showPush = true;
528
+                    }
529
+                    elseif (is_numeric($cmds[1])) {
530
+                        $this->showTermSec = $cmds[1];
531
+                    }
532
+                    else {
533
+                        $this->status = sprintf("Option '%s' unknown", $cmds[1]);
534
+                        $this->statusexpire = $this->currenttime + 5;
535
+                    }
536
+                }
537
+                elseif ($cmds[0] == "reset" || $cmds[0] == "r") {
538
+                    $this->filter = false;
539
+                    $this->wide = false;
540
+                    $this->helpexpire = 0;
541
+                    $this->status = "reset";
542
+                    $this->statusexpire = $this->currenttime + 2;
543
+                }
544
+                // enable/disable wide view
545
+                elseif ($cmds[0] == "wide" || $cmds[0] == "w") {
546
+                    $this->wide = !$this->wide;
547
+                    $this->status = ($this->wide) ? "w i d e  view" : "normal view";
548
+                    $this->statusexpire = $this->currenttime + 2;
549
+                }
550
+                elseif ($cmds[0] == "help" || $cmds[0] == "h") {
551
+                    $this->helpexpire = $this->currenttime + 20;
552
+                }
553
+                // grep the log file
554
+                elseif (($cmds[0] == "log" || $cmds[0] == "l") && isset($cmds[1])) {
555
+                    if (!file_exists(LOGFILE)) {
556
+                        $this->status = "Logfile can not be found: " . LOGFILE;
557
+                    }
558
+                    else {
559
+                        system('bash -c "fgrep -a ' . escapeshellarg($cmds[1]) . ' ' . LOGFILE . ' | less +G" > `tty`');
560
+                        $this->status = "Returning from log, updating data";
561
+                    }
562
+                    $this->statusexpire = time() + 5; // it might be much "later" now
563
+                }
564
+                // tail the log file
565
+                elseif (($cmds[0] == "tail" || $cmds[0] == "t")) {
566
+                    if (!file_exists(LOGFILE)) {
567
+                        $this->status = "Logfile can not be found: " . LOGFILE;
568
+                    }
569
+                    else {
570
+                        $this->doingTail = true;
571
+                        $this->scrClear();
572
+                        $this->scrPrintAt(1, 0, $this->scrAsBold("Press CTRL+C to return to grommunio-sync-top\n\n"));
573
+                        $secondary = "";
574
+                        if (isset($cmds[1])) {
575
+                            $secondary = " -n 200 | grep " . escapeshellarg($cmds[1]);
576
+                        }
577
+                        system('bash -c "tail -f ' . LOGFILE . $secondary . '" > `tty`');
578
+                        $this->doingTail = false;
579
+                        $this->status = "Returning from tail, updating data";
580
+                    }
581
+                    $this->statusexpire = time() + 5; // it might be much "later" now
582
+                }
583
+                // tail the error log file
584
+                elseif (($cmds[0] == "error" || $cmds[0] == "e")) {
585
+                    if (!file_exists(LOGERRORFILE)) {
586
+                        $this->status = "Error logfile can not be found: " . LOGERRORFILE;
587
+                    }
588
+                    else {
589
+                        $this->doingTail = true;
590
+                        $this->scrClear();
591
+                        $this->scrPrintAt(1, 0, $this->scrAsBold("Press CTRL+C to return to grommunio-sync-top\n\n"));
592
+                        $secondary = "";
593
+                        if (isset($cmds[1])) {
594
+                            $secondary = " -n 200 | grep " . escapeshellarg($cmds[1]);
595
+                        }
596
+                        system('bash -c "tail -f ' . LOGERRORFILE . $secondary . '" > `tty`');
597
+                        $this->doingTail = false;
598
+                        $this->status = "Returning from tail, updating data";
599
+                    }
600
+                    $this->statusexpire = time() + 5; // it might be much "later" now
601
+                }
602
+                elseif ($cmds[0] != "") {
603
+                    $this->status = sprintf("Command '%s' unknown", $cmds[0]);
604
+                    $this->statusexpire = $this->currenttime + 8;
605
+                }
606
+                $this->action = "";
607
+            }
608
+        }
609
+    }
610
+
611
+    /**
612
+     * Signal handler function.
613
+     *
614
+     * @param int $signo signal number
615
+     *
616
+     * @return
617
+     */
618
+    public function SignalHandler($signo) {
619
+        // don't terminate if the signal was sent by terminating tail
620
+        if (!$this->doingTail) {
621
+            $this->topCollector->CollectData(true);
622
+            $this->topCollector->ClearLatest(true);
623
+            $this->terminate = true;
624
+        }
625
+    }
626
+
627
+    /**
628
+     * Returns usage instructions.
629
+     *
630
+     * @return string
631
+     */
632
+    public function UsageInstructions() {
633
+        $help = "Usage:\n\tgrommunio-sync-top.php\n\n" .
634
+                "  grommunio-sync-top is a live top-like overview of what grommunio-sync is doing. It does not have specific command line options.\n\n" .
635
+                "  When grommunio-sync-top is running you can specify certain actions and options which can be executed (listed below).\n" .
636
+                "  This help information can also be shown inside grommunio-sync-top by hitting 'help' or 'h'.\n\n";
637
+        $scrhelp = $this->scrHelp();
638
+        unset($scrhelp[0]);
639
+
640
+        $help .= implode("\n", $scrhelp);
641
+        $help .= "\n\n";
642
+
643
+        return $help;
644
+    }
645
+
646
+    /**
647
+     * Prints a 'help' text at the end of the page.
648
+     *
649
+     * @return array with help lines
650
+     */
651
+    private function scrHelp() {
652
+        $h = [];
653
+        $secs = $this->helpexpire - $this->currenttime;
654
+        $h[] = "Actions supported by grommunio-sync-top (help page still displayed for " . $secs . "secs)";
655
+        $h[] = "  " . $this->scrAsBold("Action") . "\t\t" . $this->scrAsBold("Comment");
656
+        $h[] = "  " . $this->scrAsBold("h") . " or " . $this->scrAsBold("help") . "\t\tDisplays this information.";
657
+        $h[] = "  " . $this->scrAsBold("q") . ", " . $this->scrAsBold("quit") . " or " . $this->scrAsBold(":q") . "\t\tExits grommunio-sync-top.";
658
+        $h[] = "  " . $this->scrAsBold("w") . " or " . $this->scrAsBold("wide") . "\t\tTries not to truncate data. Automatically done if more than 180 columns available.";
659
+        $h[] = "  " . $this->scrAsBold("f:VAL") . " or " . $this->scrAsBold("filter:VAL") . "\tOnly display connections which contain VAL. This value is case-insensitive.";
660
+        $h[] = "  " . $this->scrAsBold("f:") . " or " . $this->scrAsBold("filter:") . "\t\tWithout a search word: resets the filter.";
661
+        $h[] = "  " . $this->scrAsBold("l:STR") . " or " . $this->scrAsBold("log:STR") . "\tIssues 'less +G' on the logfile, after grepping on the optional STR.";
662
+        $h[] = "  " . $this->scrAsBold("t:STR") . " or " . $this->scrAsBold("tail:STR") . "\tIssues 'tail -f' on the logfile, grepping for optional STR.";
663
+        $h[] = "  " . $this->scrAsBold("e:STR") . " or " . $this->scrAsBold("error:STR") . "\tIssues 'tail -f' on the error logfile, grepping for optional STR.";
664
+        $h[] = "  " . $this->scrAsBold("r") . " or " . $this->scrAsBold("reset") . "\t\tResets 'wide' or 'filter'.";
665
+        $h[] = "  " . $this->scrAsBold("o:") . " or " . $this->scrAsBold("option:") . "\t\tSets display options. Valid options specified below";
666
+        $h[] = "  " . $this->scrAsBold("  p") . " or " . $this->scrAsBold("push") . "\t\tLists/not lists active and open push connections.";
667
+        $h[] = "  " . $this->scrAsBold("  a") . " or " . $this->scrAsBold("action") . "\t\tLists only active connections.";
668
+        $h[] = "  " . $this->scrAsBold("  u") . " or " . $this->scrAsBold("unknown") . "\tLists only unknown connections.";
669
+        $h[] = "  " . $this->scrAsBold("  10") . " or " . $this->scrAsBold("20") . "\t\tLists terminated connections for 10 or 20 seconds. Any other number can be used.";
670
+        $h[] = "  " . $this->scrAsBold("  d") . " or " . $this->scrAsBold("default") . "\tUses default options";
671
+
672
+        return $h;
673
+    }
674
+
675
+    /**
676
+     * Encapsulates string with different color escape characters.
677
+     *
678
+     * @param string $text
679
+     *
680
+     * @return string same text as bold
681
+     */
682
+    private function scrAsBold($text) {
683
+        return "\033[01m" . $text . "\033[0m";
684
+    }
685
+
686
+    /**
687
+     * Prints one line of precessed data.
688
+     *
689
+     * @param array $l line information
690
+     *
691
+     * @return string
692
+     */
693
+    private function getLine($l) {
694
+        if ($this->wide === true) {
695
+            return sprintf("%s%s%s%s%s%s%s%s", $this->ptStr($l['pid'], 6), $this->ptStr($l['ip'], 16), $this->ptStr($l['user'], 24), $this->ptStr($l['command'], 16), $this->ptStr($this->sec2min($l['time']), 8), $this->ptStr($l['devagent'], 28), $this->ptStr($l['devid'], 33, true), $l['addinfo']);
696
+        }
697
+
698
+        return sprintf("%s%s%s%s%s%s%s%s", $this->ptStr($l['pid'], 6), $this->ptStr($l['ip'], 16), $this->ptStr($l['user'], 8), $this->ptStr($l['command'], 8), $this->ptStr($this->sec2min($l['time']), 6), $this->ptStr($l['devagent'], 20), $this->ptStr($l['devid'], 12, true), $l['addinfo']);
699
+    }
700
+
701
+    /**
702
+     * Pads and trims string.
703
+     *
704
+     * @param string $str       to be trimmed/padded
705
+     * @param int    $size      characters to be considered
706
+     * @param bool   $cutmiddle (optional) indicates where to long information should
707
+     *                          be trimmed of, false means at the end
708
+     *
709
+     * @return string
710
+     */
711
+    private function ptStr($str, $size, $cutmiddle = false) {
712
+        if (strlen($str) < $size) {
713
+            return str_pad($str, $size);
714
+        }
715
+        if ($cutmiddle == true) {
716
+            $cut = ($size - 2) / 2;
717
+
718
+            return $this->ptStr(substr($str, 0, $cut) . ".." . substr($str, (-1) * ($cut - 1)), $size);
719
+        }
720
+
721
+        return substr($str, 0, $size - 3) . ".. ";
722
+    }
723
+
724
+    /**
725
+     * Tries to discover the size of the current terminal.
726
+     *
727
+     * @return array 'width' and 'height' as keys
728
+     */
729
+    private function scrGetSize() {
730
+        $tty = strtolower(exec('stty -a | fgrep columns'));
731
+        if (preg_match_all("/rows.([0-9]+);.columns.([0-9]+);/", $tty, $output) ||
732
+            preg_match_all("/([0-9]+).rows;.([0-9]+).columns;/", $tty, $output)) {
733
+            return ['width' => $output[2][0], 'height' => $output[1][0]];
734
+        }
735
+
736
+        return ['width' => 80, 'height' => 24];
737
+    }
738
+
739
+    /**
740
+     * Returns the version of the current grommunio-sync installation.
741
+     *
742
+     * @return string
743
+     */
744
+    private function getVersion() {
745
+        return GROMMUNIOSYNC_VERSION;
746
+    }
747
+
748
+    /**
749
+     * Converts seconds in MM:SS.
750
+     *
751
+     * @param int $s seconds
752
+     *
753
+     * @return string
754
+     */
755
+    private function sec2min($s) {
756
+        if (!is_int($s)) {
757
+            return $s;
758
+        }
759
+
760
+        return sprintf("%02.2d:%02.2d", floor($s / 60), $s % 60);
761
+    }
762
+
763
+    /**
764
+     * Resets the default colors of the terminal.
765
+     *
766
+     * @return
767
+     */
768
+    private function scrDefaultColors() {
769
+        echo "\033[0m";
770
+    }
771
+
772
+    /**
773
+     * Clears screen of the terminal.
774
+     *
775
+     * @param array $data
776
+     *
777
+     * @return
778
+     */
779
+    public function scrClear() {
780
+        echo "\033[2J";
781
+    }
782
+
783
+    /**
784
+     * Prints a text at a specific screen/terminal coordinates.
785
+     *
786
+     * @param int    $row  row number
787
+     * @param int    $col  column number
788
+     * @param string $text to be printed
789
+     *
790
+     * @return
791
+     */
792
+    private function scrPrintAt($row, $col, $text = "") {
793
+        echo "\033[" . $row . ";" . $col . "H" . $text;
794
+    }
795 795
 }
Please login to merge, or discard this patch.
Spacing   +48 added lines, -48 removed lines patch added patch discarded remove patch
@@ -20,11 +20,11 @@  discard block
 block discarded – undo
20 20
  * MAIN
21 21
  */
22 22
 	declare(ticks=1);
23
-	define('BASE_PATH_CLI', dirname(__FILE__) . "/");
24
-	set_include_path(get_include_path() . PATH_SEPARATOR . BASE_PATH_CLI);
23
+	define('BASE_PATH_CLI', dirname(__FILE__)."/");
24
+	set_include_path(get_include_path().PATH_SEPARATOR.BASE_PATH_CLI);
25 25
 
26 26
 	if (!defined('GSYNC_CONFIG')) {
27
-		define('GSYNC_CONFIG', BASE_PATH_CLI . 'config.php');
27
+		define('GSYNC_CONFIG', BASE_PATH_CLI.'config.php');
28 28
 	}
29 29
 
30 30
 	include_once GSYNC_CONFIG;
@@ -59,7 +59,7 @@  discard block
 block discarded – undo
59 59
 		}
60 60
 	}
61 61
 	catch (GSyncException $zpe) {
62
-		fwrite(STDERR, get_class($zpe) . ": " . $zpe->getMessage() . "\n");
62
+		fwrite(STDERR, get_class($zpe).": ".$zpe->getMessage()."\n");
63 63
 
64 64
 		exit(1);
65 65
 	}
@@ -259,13 +259,13 @@  discard block
 block discarded – undo
259 259
 
260 260
 						$lastUpdate = $this->currenttime - $line["update"];
261 261
 						if ($this->currenttime - $line["update"] < 2) {
262
-							$this->linesActive[$line["update"] . $line["pid"]] = $line;
262
+							$this->linesActive[$line["update"].$line["pid"]] = $line;
263 263
 						}
264 264
 						elseif (($line['push'] === true && $lastUpdate > ($this->pingInterval + 2)) || ($line['push'] !== true && $lastUpdate > 4)) {
265
-							$this->linesUnknown[$line["update"] . $line["pid"]] = $line;
265
+							$this->linesUnknown[$line["update"].$line["pid"]] = $line;
266 266
 						}
267 267
 						else {
268
-							$this->linesOpen[$line["update"] . $line["pid"]] = $line;
268
+							$this->linesOpen[$line["update"].$line["pid"]] = $line;
269 269
 						}
270 270
 					}
271 271
 					else {
@@ -291,7 +291,7 @@  discard block
 block discarded – undo
291 291
 						}
292 292
 
293 293
 						$line['time'] = $line['ended'] - $line['start'];
294
-						$this->linesTerm[$line['update'] . $line['pid']] = $line;
294
+						$this->linesTerm[$line['update'].$line['pid']] = $line;
295 295
 					}
296 296
 				}
297 297
 			}
@@ -312,7 +312,7 @@  discard block
 block discarded – undo
312 312
 	private function scrOverview() {
313 313
 		$linesAvail = $this->scrSize['height'] - 8;
314 314
 		$lc = 1;
315
-		$this->scrPrintAt($lc, 0, "\033[1mgrommunio-sync-top live statistics\033[0m\t\t\t\t\t" . @strftime("%d/%m/%Y %T") . "\n");
315
+		$this->scrPrintAt($lc, 0, "\033[1mgrommunio-sync-top live statistics\033[0m\t\t\t\t\t".@strftime("%d/%m/%Y %T")."\n");
316 316
 		++$lc;
317 317
 
318 318
 		$this->scrPrintAt($lc, 0, sprintf("Open connections: %d\t\t\t\tUsers:\t %d\tgrommunio-sync:   %s ", count($this->activeConn), count($this->activeUsers), $this->getVersion()));
@@ -323,7 +323,7 @@  discard block
 block discarded – undo
323 323
 		++$lc;
324 324
 		++$lc;
325 325
 
326
-		$this->scrPrintAt($lc, 0, "\033[4m" . $this->getLine(['pid' => 'PID', 'ip' => 'IP', 'user' => 'USER', 'command' => 'COMMAND', 'time' => 'TIME', 'devagent' => 'AGENT', 'devid' => 'DEVID', 'addinfo' => 'Additional Information']) . str_repeat(" ", 20) . "\033[0m");
326
+		$this->scrPrintAt($lc, 0, "\033[4m".$this->getLine(['pid' => 'PID', 'ip' => 'IP', 'user' => 'USER', 'command' => 'COMMAND', 'time' => 'TIME', 'devagent' => 'AGENT', 'devid' => 'DEVID', 'addinfo' => 'Additional Information']).str_repeat(" ", 20)."\033[0m");
327 327
 		++$lc;
328 328
 
329 329
 		// print help text if requested
@@ -371,7 +371,7 @@  discard block
 block discarded – undo
371 371
 				break;
372 372
 			}
373 373
 
374
-			$this->scrPrintAt($lc, 0, "\033[01m" . $this->getLine($l) . "\033[0m");
374
+			$this->scrPrintAt($lc, 0, "\033[01m".$this->getLine($l)."\033[0m");
375 375
 			++$lc;
376 376
 			++$linesprinted;
377 377
 		}
@@ -397,7 +397,7 @@  discard block
 block discarded – undo
397 397
 			if ($l['push'] == false && $time - $l["start"] > 30) {
398 398
 				$color = "1;31m";
399 399
 			}
400
-			$this->scrPrintAt($lc, 0, "\033[0" . $color . $this->getLine($l) . "\033[0m");
400
+			$this->scrPrintAt($lc, 0, "\033[0".$color.$this->getLine($l)."\033[0m");
401 401
 			++$lc;
402 402
 			++$linesprinted;
403 403
 		}
@@ -412,7 +412,7 @@  discard block
 block discarded – undo
412 412
 				break;
413 413
 			}
414 414
 
415
-			$this->scrPrintAt($lc, 0, "\033[01;30m" . $this->getLine($l) . "\033[0m");
415
+			$this->scrPrintAt($lc, 0, "\033[01;30m".$this->getLine($l)."\033[0m");
416 416
 			++$lc;
417 417
 			++$linesprinted;
418 418
 		}
@@ -430,7 +430,7 @@  discard block
 block discarded – undo
430 430
 
431 431
 		// show request information and help command
432 432
 		if ($this->starttime + 6 > $this->currenttime) {
433
-			$this->status = sprintf("Requesting information (takes up to %dsecs)", $this->pingInterval) . str_repeat(".", ($this->currenttime - $this->starttime)) . "  type \033[01;31mh\033[00;31m or \033[01;31mhelp\033[00;31m for usage instructions";
433
+			$this->status = sprintf("Requesting information (takes up to %dsecs)", $this->pingInterval).str_repeat(".", ($this->currenttime - $this->starttime))."  type \033[01;31mh\033[00;31m or \033[01;31mhelp\033[00;31m for usage instructions";
434 434
 			$this->statusexpire = $this->currenttime + 1;
435 435
 		}
436 436
 
@@ -448,7 +448,7 @@  discard block
 block discarded – undo
448 448
 		}
449 449
 
450 450
 		if ($this->showTermSec != self::SHOW_TERM_DEFAULT_TIME) {
451
-			$str .= "\033[01;32mTerminated: " . $this->showTermSec . "s\033[0m   ";
451
+			$str .= "\033[01;32mTerminated: ".$this->showTermSec."s\033[0m   ";
452 452
 		}
453 453
 
454 454
 		if ($this->filter !== false || ($this->status !== false && $this->statusexpire > $this->currenttime)) {
@@ -463,7 +463,7 @@  discard block
 block discarded – undo
463 463
 		}
464 464
 		$this->scrPrintAt(5, 0, $str);
465 465
 
466
-		$this->scrPrintAt(4, 0, "Action: \033[01m" . $this->action . "\033[0m");
466
+		$this->scrPrintAt(4, 0, "Action: \033[01m".$this->action."\033[0m");
467 467
 	}
468 468
 
469 469
 	/**
@@ -553,10 +553,10 @@  discard block
 block discarded – undo
553 553
 				// grep the log file
554 554
 				elseif (($cmds[0] == "log" || $cmds[0] == "l") && isset($cmds[1])) {
555 555
 					if (!file_exists(LOGFILE)) {
556
-						$this->status = "Logfile can not be found: " . LOGFILE;
556
+						$this->status = "Logfile can not be found: ".LOGFILE;
557 557
 					}
558 558
 					else {
559
-						system('bash -c "fgrep -a ' . escapeshellarg($cmds[1]) . ' ' . LOGFILE . ' | less +G" > `tty`');
559
+						system('bash -c "fgrep -a '.escapeshellarg($cmds[1]).' '.LOGFILE.' | less +G" > `tty`');
560 560
 						$this->status = "Returning from log, updating data";
561 561
 					}
562 562
 					$this->statusexpire = time() + 5; // it might be much "later" now
@@ -564,7 +564,7 @@  discard block
 block discarded – undo
564 564
 				// tail the log file
565 565
 				elseif (($cmds[0] == "tail" || $cmds[0] == "t")) {
566 566
 					if (!file_exists(LOGFILE)) {
567
-						$this->status = "Logfile can not be found: " . LOGFILE;
567
+						$this->status = "Logfile can not be found: ".LOGFILE;
568 568
 					}
569 569
 					else {
570 570
 						$this->doingTail = true;
@@ -572,9 +572,9 @@  discard block
 block discarded – undo
572 572
 						$this->scrPrintAt(1, 0, $this->scrAsBold("Press CTRL+C to return to grommunio-sync-top\n\n"));
573 573
 						$secondary = "";
574 574
 						if (isset($cmds[1])) {
575
-							$secondary = " -n 200 | grep " . escapeshellarg($cmds[1]);
575
+							$secondary = " -n 200 | grep ".escapeshellarg($cmds[1]);
576 576
 						}
577
-						system('bash -c "tail -f ' . LOGFILE . $secondary . '" > `tty`');
577
+						system('bash -c "tail -f '.LOGFILE.$secondary.'" > `tty`');
578 578
 						$this->doingTail = false;
579 579
 						$this->status = "Returning from tail, updating data";
580 580
 					}
@@ -583,7 +583,7 @@  discard block
 block discarded – undo
583 583
 				// tail the error log file
584 584
 				elseif (($cmds[0] == "error" || $cmds[0] == "e")) {
585 585
 					if (!file_exists(LOGERRORFILE)) {
586
-						$this->status = "Error logfile can not be found: " . LOGERRORFILE;
586
+						$this->status = "Error logfile can not be found: ".LOGERRORFILE;
587 587
 					}
588 588
 					else {
589 589
 						$this->doingTail = true;
@@ -591,9 +591,9 @@  discard block
 block discarded – undo
591 591
 						$this->scrPrintAt(1, 0, $this->scrAsBold("Press CTRL+C to return to grommunio-sync-top\n\n"));
592 592
 						$secondary = "";
593 593
 						if (isset($cmds[1])) {
594
-							$secondary = " -n 200 | grep " . escapeshellarg($cmds[1]);
594
+							$secondary = " -n 200 | grep ".escapeshellarg($cmds[1]);
595 595
 						}
596
-						system('bash -c "tail -f ' . LOGERRORFILE . $secondary . '" > `tty`');
596
+						system('bash -c "tail -f '.LOGERRORFILE.$secondary.'" > `tty`');
597 597
 						$this->doingTail = false;
598 598
 						$this->status = "Returning from tail, updating data";
599 599
 					}
@@ -630,9 +630,9 @@  discard block
 block discarded – undo
630 630
 	 * @return string
631 631
 	 */
632 632
 	public function UsageInstructions() {
633
-		$help = "Usage:\n\tgrommunio-sync-top.php\n\n" .
634
-				"  grommunio-sync-top is a live top-like overview of what grommunio-sync is doing. It does not have specific command line options.\n\n" .
635
-				"  When grommunio-sync-top is running you can specify certain actions and options which can be executed (listed below).\n" .
633
+		$help = "Usage:\n\tgrommunio-sync-top.php\n\n".
634
+				"  grommunio-sync-top is a live top-like overview of what grommunio-sync is doing. It does not have specific command line options.\n\n".
635
+				"  When grommunio-sync-top is running you can specify certain actions and options which can be executed (listed below).\n".
636 636
 				"  This help information can also be shown inside grommunio-sync-top by hitting 'help' or 'h'.\n\n";
637 637
 		$scrhelp = $this->scrHelp();
638 638
 		unset($scrhelp[0]);
@@ -651,23 +651,23 @@  discard block
 block discarded – undo
651 651
 	private function scrHelp() {
652 652
 		$h = [];
653 653
 		$secs = $this->helpexpire - $this->currenttime;
654
-		$h[] = "Actions supported by grommunio-sync-top (help page still displayed for " . $secs . "secs)";
655
-		$h[] = "  " . $this->scrAsBold("Action") . "\t\t" . $this->scrAsBold("Comment");
656
-		$h[] = "  " . $this->scrAsBold("h") . " or " . $this->scrAsBold("help") . "\t\tDisplays this information.";
657
-		$h[] = "  " . $this->scrAsBold("q") . ", " . $this->scrAsBold("quit") . " or " . $this->scrAsBold(":q") . "\t\tExits grommunio-sync-top.";
658
-		$h[] = "  " . $this->scrAsBold("w") . " or " . $this->scrAsBold("wide") . "\t\tTries not to truncate data. Automatically done if more than 180 columns available.";
659
-		$h[] = "  " . $this->scrAsBold("f:VAL") . " or " . $this->scrAsBold("filter:VAL") . "\tOnly display connections which contain VAL. This value is case-insensitive.";
660
-		$h[] = "  " . $this->scrAsBold("f:") . " or " . $this->scrAsBold("filter:") . "\t\tWithout a search word: resets the filter.";
661
-		$h[] = "  " . $this->scrAsBold("l:STR") . " or " . $this->scrAsBold("log:STR") . "\tIssues 'less +G' on the logfile, after grepping on the optional STR.";
662
-		$h[] = "  " . $this->scrAsBold("t:STR") . " or " . $this->scrAsBold("tail:STR") . "\tIssues 'tail -f' on the logfile, grepping for optional STR.";
663
-		$h[] = "  " . $this->scrAsBold("e:STR") . " or " . $this->scrAsBold("error:STR") . "\tIssues 'tail -f' on the error logfile, grepping for optional STR.";
664
-		$h[] = "  " . $this->scrAsBold("r") . " or " . $this->scrAsBold("reset") . "\t\tResets 'wide' or 'filter'.";
665
-		$h[] = "  " . $this->scrAsBold("o:") . " or " . $this->scrAsBold("option:") . "\t\tSets display options. Valid options specified below";
666
-		$h[] = "  " . $this->scrAsBold("  p") . " or " . $this->scrAsBold("push") . "\t\tLists/not lists active and open push connections.";
667
-		$h[] = "  " . $this->scrAsBold("  a") . " or " . $this->scrAsBold("action") . "\t\tLists only active connections.";
668
-		$h[] = "  " . $this->scrAsBold("  u") . " or " . $this->scrAsBold("unknown") . "\tLists only unknown connections.";
669
-		$h[] = "  " . $this->scrAsBold("  10") . " or " . $this->scrAsBold("20") . "\t\tLists terminated connections for 10 or 20 seconds. Any other number can be used.";
670
-		$h[] = "  " . $this->scrAsBold("  d") . " or " . $this->scrAsBold("default") . "\tUses default options";
654
+		$h[] = "Actions supported by grommunio-sync-top (help page still displayed for ".$secs."secs)";
655
+		$h[] = "  ".$this->scrAsBold("Action")."\t\t".$this->scrAsBold("Comment");
656
+		$h[] = "  ".$this->scrAsBold("h")." or ".$this->scrAsBold("help")."\t\tDisplays this information.";
657
+		$h[] = "  ".$this->scrAsBold("q").", ".$this->scrAsBold("quit")." or ".$this->scrAsBold(":q")."\t\tExits grommunio-sync-top.";
658
+		$h[] = "  ".$this->scrAsBold("w")." or ".$this->scrAsBold("wide")."\t\tTries not to truncate data. Automatically done if more than 180 columns available.";
659
+		$h[] = "  ".$this->scrAsBold("f:VAL")." or ".$this->scrAsBold("filter:VAL")."\tOnly display connections which contain VAL. This value is case-insensitive.";
660
+		$h[] = "  ".$this->scrAsBold("f:")." or ".$this->scrAsBold("filter:")."\t\tWithout a search word: resets the filter.";
661
+		$h[] = "  ".$this->scrAsBold("l:STR")." or ".$this->scrAsBold("log:STR")."\tIssues 'less +G' on the logfile, after grepping on the optional STR.";
662
+		$h[] = "  ".$this->scrAsBold("t:STR")." or ".$this->scrAsBold("tail:STR")."\tIssues 'tail -f' on the logfile, grepping for optional STR.";
663
+		$h[] = "  ".$this->scrAsBold("e:STR")." or ".$this->scrAsBold("error:STR")."\tIssues 'tail -f' on the error logfile, grepping for optional STR.";
664
+		$h[] = "  ".$this->scrAsBold("r")." or ".$this->scrAsBold("reset")."\t\tResets 'wide' or 'filter'.";
665
+		$h[] = "  ".$this->scrAsBold("o:")." or ".$this->scrAsBold("option:")."\t\tSets display options. Valid options specified below";
666
+		$h[] = "  ".$this->scrAsBold("  p")." or ".$this->scrAsBold("push")."\t\tLists/not lists active and open push connections.";
667
+		$h[] = "  ".$this->scrAsBold("  a")." or ".$this->scrAsBold("action")."\t\tLists only active connections.";
668
+		$h[] = "  ".$this->scrAsBold("  u")." or ".$this->scrAsBold("unknown")."\tLists only unknown connections.";
669
+		$h[] = "  ".$this->scrAsBold("  10")." or ".$this->scrAsBold("20")."\t\tLists terminated connections for 10 or 20 seconds. Any other number can be used.";
670
+		$h[] = "  ".$this->scrAsBold("  d")." or ".$this->scrAsBold("default")."\tUses default options";
671 671
 
672 672
 		return $h;
673 673
 	}
@@ -680,7 +680,7 @@  discard block
 block discarded – undo
680 680
 	 * @return string same text as bold
681 681
 	 */
682 682
 	private function scrAsBold($text) {
683
-		return "\033[01m" . $text . "\033[0m";
683
+		return "\033[01m".$text."\033[0m";
684 684
 	}
685 685
 
686 686
 	/**
@@ -715,10 +715,10 @@  discard block
 block discarded – undo
715 715
 		if ($cutmiddle == true) {
716 716
 			$cut = ($size - 2) / 2;
717 717
 
718
-			return $this->ptStr(substr($str, 0, $cut) . ".." . substr($str, (-1) * ($cut - 1)), $size);
718
+			return $this->ptStr(substr($str, 0, $cut)."..".substr($str, (-1) * ($cut - 1)), $size);
719 719
 		}
720 720
 
721
-		return substr($str, 0, $size - 3) . ".. ";
721
+		return substr($str, 0, $size - 3).".. ";
722 722
 	}
723 723
 
724 724
 	/**
@@ -790,6 +790,6 @@  discard block
 block discarded – undo
790 790
 	 * @return
791 791
 	 */
792 792
 	private function scrPrintAt($row, $col, $text = "") {
793
-		echo "\033[" . $row . ";" . $col . "H" . $text;
793
+		echo "\033[".$row.";".$col."H".$text;
794 794
 	}
795 795
 }
Please login to merge, or discard this patch.
Braces   +22 added lines, -44 removed lines patch added patch discarded remove patch
@@ -53,12 +53,10 @@  discard block
 block discarded – undo
53 53
 			$zpt->run();
54 54
 			$zpt->scrClear();
55 55
 			system("stty sane");
56
-		}
57
-		else {
56
+		} else {
58 57
 			echo "grommunio-sync interprocess communication (IPC) is not available or TopCollector is disabled.\n";
59 58
 		}
60
-	}
61
-	catch (GSyncException $zpe) {
59
+	} catch (GSyncException $zpe) {
62 60
 		fwrite(STDERR, get_class($zpe) . ": " . $zpe->getMessage() . "\n");
63 61
 
64 62
 		exit(1);
@@ -173,8 +171,7 @@  discard block
 block discarded – undo
173 171
 			if ($this->scrSize['width'] != $s['width']) {
174 172
 				if ($s['width'] > 180) {
175 173
 					$this->wide = true;
176
-				}
177
-				else {
174
+				} else {
178 175
 					$this->wide = false;
179 176
 				}
180 177
 			}
@@ -260,15 +257,12 @@  discard block
 block discarded – undo
260 257
 						$lastUpdate = $this->currenttime - $line["update"];
261 258
 						if ($this->currenttime - $line["update"] < 2) {
262 259
 							$this->linesActive[$line["update"] . $line["pid"]] = $line;
263
-						}
264
-						elseif (($line['push'] === true && $lastUpdate > ($this->pingInterval + 2)) || ($line['push'] !== true && $lastUpdate > 4)) {
260
+						} elseif (($line['push'] === true && $lastUpdate > ($this->pingInterval + 2)) || ($line['push'] !== true && $lastUpdate > 4)) {
265 261
 							$this->linesUnknown[$line["update"] . $line["pid"]] = $line;
266
-						}
267
-						else {
262
+						} else {
268 263
 							$this->linesOpen[$line["update"] . $line["pid"]] = $line;
269 264
 						}
270
-					}
271
-					else {
265
+					} else {
272 266
 						// do not show terminated + expired connections
273 267
 						if ($this->currenttime > $line['ended'] + $this->showTermSec) {
274 268
 							continue;
@@ -490,51 +484,40 @@  discard block
 block discarded – undo
490 484
 					$this->topCollector->ClearLatest(true);
491 485
 
492 486
 					$this->terminate = true;
493
-				}
494
-				elseif ($cmds[0] == "clear") {
487
+				} elseif ($cmds[0] == "clear") {
495 488
 					$this->topCollector->ClearLatest(true);
496 489
 					$this->topCollector->CollectData(true);
497 490
 					$this->topCollector->ReInitIPC();
498
-				}
499
-				elseif ($cmds[0] == "filter" || $cmds[0] == "f") {
491
+				} elseif ($cmds[0] == "filter" || $cmds[0] == "f") {
500 492
 					if (!isset($cmds[1]) || $cmds[1] == "") {
501 493
 						$this->filter = false;
502 494
 						$this->status = "No filter";
503 495
 						$this->statusexpire = $this->currenttime + 5;
504
-					}
505
-					else {
496
+					} else {
506 497
 						$this->filter = $cmds[1];
507 498
 						$this->status = false;
508 499
 					}
509
-				}
510
-				elseif ($cmds[0] == "option" || $cmds[0] == "o") {
500
+				} elseif ($cmds[0] == "option" || $cmds[0] == "o") {
511 501
 					if (!isset($cmds[1]) || $cmds[1] == "") {
512 502
 						$this->status = "Option value needs to be specified. See 'help' or 'h' for instructions";
513 503
 						$this->statusexpire = $this->currenttime + 5;
514
-					}
515
-					elseif ($cmds[1] == "p" || $cmds[1] == "push" || $cmds[1] == "ping") {
504
+					} elseif ($cmds[1] == "p" || $cmds[1] == "push" || $cmds[1] == "ping") {
516 505
 						$this->showPush = !$this->showPush;
517
-					}
518
-					elseif ($cmds[1] == "a" || $cmds[1] == "active") {
506
+					} elseif ($cmds[1] == "a" || $cmds[1] == "active") {
519 507
 						$this->showOption = self::SHOW_ACTIVE_ONLY;
520
-					}
521
-					elseif ($cmds[1] == "u" || $cmds[1] == "unknown") {
508
+					} elseif ($cmds[1] == "u" || $cmds[1] == "unknown") {
522 509
 						$this->showOption = self::SHOW_UNKNOWN_ONLY;
523
-					}
524
-					elseif ($cmds[1] == "d" || $cmds[1] == "default") {
510
+					} elseif ($cmds[1] == "d" || $cmds[1] == "default") {
525 511
 						$this->showOption = self::SHOW_DEFAULT;
526 512
 						$this->showTermSec = self::SHOW_TERM_DEFAULT_TIME;
527 513
 						$this->showPush = true;
528
-					}
529
-					elseif (is_numeric($cmds[1])) {
514
+					} elseif (is_numeric($cmds[1])) {
530 515
 						$this->showTermSec = $cmds[1];
531
-					}
532
-					else {
516
+					} else {
533 517
 						$this->status = sprintf("Option '%s' unknown", $cmds[1]);
534 518
 						$this->statusexpire = $this->currenttime + 5;
535 519
 					}
536
-				}
537
-				elseif ($cmds[0] == "reset" || $cmds[0] == "r") {
520
+				} elseif ($cmds[0] == "reset" || $cmds[0] == "r") {
538 521
 					$this->filter = false;
539 522
 					$this->wide = false;
540 523
 					$this->helpexpire = 0;
@@ -546,16 +529,14 @@  discard block
 block discarded – undo
546 529
 					$this->wide = !$this->wide;
547 530
 					$this->status = ($this->wide) ? "w i d e  view" : "normal view";
548 531
 					$this->statusexpire = $this->currenttime + 2;
549
-				}
550
-				elseif ($cmds[0] == "help" || $cmds[0] == "h") {
532
+				} elseif ($cmds[0] == "help" || $cmds[0] == "h") {
551 533
 					$this->helpexpire = $this->currenttime + 20;
552 534
 				}
553 535
 				// grep the log file
554 536
 				elseif (($cmds[0] == "log" || $cmds[0] == "l") && isset($cmds[1])) {
555 537
 					if (!file_exists(LOGFILE)) {
556 538
 						$this->status = "Logfile can not be found: " . LOGFILE;
557
-					}
558
-					else {
539
+					} else {
559 540
 						system('bash -c "fgrep -a ' . escapeshellarg($cmds[1]) . ' ' . LOGFILE . ' | less +G" > `tty`');
560 541
 						$this->status = "Returning from log, updating data";
561 542
 					}
@@ -565,8 +546,7 @@  discard block
 block discarded – undo
565 546
 				elseif (($cmds[0] == "tail" || $cmds[0] == "t")) {
566 547
 					if (!file_exists(LOGFILE)) {
567 548
 						$this->status = "Logfile can not be found: " . LOGFILE;
568
-					}
569
-					else {
549
+					} else {
570 550
 						$this->doingTail = true;
571 551
 						$this->scrClear();
572 552
 						$this->scrPrintAt(1, 0, $this->scrAsBold("Press CTRL+C to return to grommunio-sync-top\n\n"));
@@ -584,8 +564,7 @@  discard block
 block discarded – undo
584 564
 				elseif (($cmds[0] == "error" || $cmds[0] == "e")) {
585 565
 					if (!file_exists(LOGERRORFILE)) {
586 566
 						$this->status = "Error logfile can not be found: " . LOGERRORFILE;
587
-					}
588
-					else {
567
+					} else {
589 568
 						$this->doingTail = true;
590 569
 						$this->scrClear();
591 570
 						$this->scrPrintAt(1, 0, $this->scrAsBold("Press CTRL+C to return to grommunio-sync-top\n\n"));
@@ -598,8 +577,7 @@  discard block
 block discarded – undo
598 577
 						$this->status = "Returning from tail, updating data";
599 578
 					}
600 579
 					$this->statusexpire = time() + 5; // it might be much "later" now
601
-				}
602
-				elseif ($cmds[0] != "") {
580
+				} elseif ($cmds[0] != "") {
603 581
 					$this->status = sprintf("Command '%s' unknown", $cmds[0]);
604 582
 					$this->statusexpire = $this->currenttime + 8;
605 583
 				}
Please login to merge, or discard this patch.
lib/request/settings.php 2 patches
Indentation   +212 added lines, -212 removed lines patch added patch discarded remove patch
@@ -8,216 +8,216 @@
 block discarded – undo
8 8
  */
9 9
 
10 10
 class Settings extends RequestProcessor {
11
-	/**
12
-	 * Handles the Settings command.
13
-	 *
14
-	 * @param int $commandCode
15
-	 *
16
-	 * @return bool
17
-	 */
18
-	public function Handle($commandCode) {
19
-		if (!self::$decoder->getElementStartTag(SYNC_SETTINGS_SETTINGS)) {
20
-			return false;
21
-		}
22
-
23
-		// save the request parameters
24
-		$request = [];
25
-
26
-		// Loop through properties. Possible are:
27
-		// - Out of office
28
-		// - DevicePassword
29
-		// - DeviceInformation
30
-		// - UserInformation
31
-		// Each of them should only be once per request. Each property must be processed in order.
32
-		WBXMLDecoder::ResetInWhile("settingsMain");
33
-		while (WBXMLDecoder::InWhile("settingsMain")) {
34
-			$propertyName = "";
35
-			if (self::$decoder->getElementStartTag(SYNC_SETTINGS_OOF)) {
36
-				$propertyName = SYNC_SETTINGS_OOF;
37
-			}
38
-			if (self::$decoder->getElementStartTag(SYNC_SETTINGS_DEVICEPW)) {
39
-				$propertyName = SYNC_SETTINGS_DEVICEPW;
40
-			}
41
-			if (self::$decoder->getElementStartTag(SYNC_SETTINGS_DEVICEINFORMATION)) {
42
-				$propertyName = SYNC_SETTINGS_DEVICEINFORMATION;
43
-			}
44
-			if (self::$decoder->getElementStartTag(SYNC_SETTINGS_USERINFORMATION)) {
45
-				$propertyName = SYNC_SETTINGS_USERINFORMATION;
46
-			}
47
-			if (self::$decoder->getElementStartTag(SYNC_SETTINGS_RIGHTSMANAGEMENTINFORMATION)) {
48
-				$propertyName = SYNC_SETTINGS_RIGHTSMANAGEMENTINFORMATION;
49
-			}
50
-			// TODO - check if it is necessary
51
-			// no property name available - break
52
-			if (!$propertyName) {
53
-				break;
54
-			}
55
-
56
-			// the property name is followed by either get or set
57
-			if (self::$decoder->getElementStartTag(SYNC_SETTINGS_GET)) {
58
-				// get is available for OOF (AS 12), user information (AS 12) and rights management (AS 14.1)
59
-				switch ($propertyName) {
60
-					case SYNC_SETTINGS_OOF:
61
-						$oofGet = new SyncOOF();
62
-						$oofGet->Decode(self::$decoder);
63
-						if (!self::$decoder->getElementEndTag()) {
64
-							return false;
65
-						} // SYNC_SETTINGS_GET
66
-						break;
67
-
68
-					case SYNC_SETTINGS_USERINFORMATION:
69
-						$userInformation = new SyncUserInformation();
70
-						break;
71
-
72
-					case SYNC_SETTINGS_RIGHTSMANAGEMENTINFORMATION:
73
-						$rmTemplates = new SyncRightsManagementTemplates();
74
-						break;
75
-
76
-					default:
77
-						// TODO: a special status code needed?
78
-						SLog::Write(LOGLEVEL_WARN, sprintf("This property ('%s') is not allowed to use get in request", $propertyName));
79
-				}
80
-			}
81
-			elseif (self::$decoder->getElementStartTag(SYNC_SETTINGS_SET)) {
82
-				// set is available for OOF, device password and device information
83
-				switch ($propertyName) {
84
-					case SYNC_SETTINGS_OOF:
85
-						$oofSet = new SyncOOF();
86
-						$oofSet->Decode(self::$decoder);
87
-						// TODO check - do it after while(1) finished?
88
-						break;
89
-
90
-					case SYNC_SETTINGS_DEVICEPW:
91
-						// TODO device password
92
-						$devicepassword = new SyncDevicePassword();
93
-						$devicepassword->Decode(self::$decoder);
94
-						break;
95
-
96
-					case SYNC_SETTINGS_DEVICEINFORMATION:
97
-						$deviceinformation = new SyncDeviceInformation();
98
-						$deviceinformation->Decode(self::$decoder);
99
-						$deviceinformation->Status = SYNC_SETTINGSSTATUS_SUCCESS;
100
-						self::$deviceManager->SaveDeviceInformation($deviceinformation);
101
-						break;
102
-
103
-					default:
104
-						// TODO: a special status code needed?
105
-						SLog::Write(LOGLEVEL_WARN, sprintf("This property ('%s') is not allowed to use set in request", $propertyName));
106
-				}
107
-
108
-				if (!self::$decoder->getElementEndTag()) {
109
-					return false;
110
-				} // SYNC_SETTINGS_SET
111
-			}
112
-			else {
113
-				SLog::Write(LOGLEVEL_WARN, sprintf("Neither get nor set found for property '%s'", $propertyName));
114
-
115
-				return false;
116
-			}
117
-
118
-			if (!self::$decoder->getElementEndTag()) {
119
-				return false;
120
-			} // SYNC_SETTINGS_OOF or SYNC_SETTINGS_DEVICEPW or SYNC_SETTINGS_DEVICEINFORMATION or SYNC_SETTINGS_USERINFORMATION
121
-
122
-			// break if it reached the endtag
123
-			$e = self::$decoder->peek();
124
-			if ($e[EN_TYPE] == EN_TYPE_ENDTAG) {
125
-				self::$decoder->getElementEndTag(); // SYNC_SETTINGS_SETTINGS
126
-
127
-				break;
128
-			}
129
-		}
130
-
131
-		$status = SYNC_SETTINGSSTATUS_SUCCESS;
132
-
133
-		// TODO put it in try catch block
134
-		// TODO implement Settings in the backend
135
-		// TODO save device information in device manager
136
-		// TODO status handling
137
-		//        $data = self::$backend->Settings($request);
138
-
139
-		self::$encoder->startWBXML();
140
-		self::$encoder->startTag(SYNC_SETTINGS_SETTINGS);
141
-
142
-		self::$encoder->startTag(SYNC_SETTINGS_STATUS);
143
-		self::$encoder->content($status);
144
-		self::$encoder->endTag(); // SYNC_SETTINGS_STATUS
145
-
146
-		// get oof settings
147
-		if (isset($oofGet)) {
148
-			$oofGet = self::$backend->Settings($oofGet);
149
-			self::$encoder->startTag(SYNC_SETTINGS_OOF);
150
-			self::$encoder->startTag(SYNC_SETTINGS_STATUS);
151
-			self::$encoder->content($oofGet->Status);
152
-			self::$encoder->endTag(); // SYNC_SETTINGS_STATUS
153
-
154
-			self::$encoder->startTag(SYNC_SETTINGS_GET);
155
-			$oofGet->Encode(self::$encoder);
156
-			self::$encoder->endTag(); // SYNC_SETTINGS_GET
157
-				self::$encoder->endTag(); // SYNC_SETTINGS_OOF
158
-		}
159
-
160
-		// get user information
161
-		// TODO none email address found
162
-		if (isset($userInformation)) {
163
-			self::$backend->Settings($userInformation);
164
-			self::$encoder->startTag(SYNC_SETTINGS_USERINFORMATION);
165
-			self::$encoder->startTag(SYNC_SETTINGS_STATUS);
166
-			self::$encoder->content($userInformation->Status);
167
-			self::$encoder->endTag(); // SYNC_SETTINGS_STATUS
168
-
169
-			self::$encoder->startTag(SYNC_SETTINGS_GET);
170
-			$userInformation->Encode(self::$encoder);
171
-			self::$encoder->endTag(); // SYNC_SETTINGS_GET
172
-				self::$encoder->endTag(); // SYNC_SETTINGS_USERINFORMATION
173
-		}
174
-
175
-		// get rights management templates
176
-		if (isset($rmTemplates)) {
177
-			self::$backend->Settings($rmTemplates);
178
-			self::$encoder->startTag(SYNC_SETTINGS_RIGHTSMANAGEMENTINFORMATION);
179
-			self::$encoder->startTag(SYNC_SETTINGS_STATUS);
180
-			self::$encoder->content($rmTemplates->Status);
181
-			self::$encoder->endTag(); // SYNC_SETTINGS_STATUS
182
-
183
-			self::$encoder->startTag(SYNC_SETTINGS_GET);
184
-			$rmTemplates->Encode(self::$encoder);
185
-			self::$encoder->endTag(); // SYNC_SETTINGS_GET
186
-				self::$encoder->endTag(); // SYNC_SETTINGS_RIGHTSMANAGEMENTINFORMATION
187
-		}
188
-
189
-		// set out of office
190
-		if (isset($oofSet)) {
191
-			$oofSet = self::$backend->Settings($oofSet);
192
-			self::$encoder->startTag(SYNC_SETTINGS_OOF);
193
-			self::$encoder->startTag(SYNC_SETTINGS_STATUS);
194
-			self::$encoder->content($oofSet->Status);
195
-			self::$encoder->endTag(); // SYNC_SETTINGS_STATUS
196
-				self::$encoder->endTag(); // SYNC_SETTINGS_OOF
197
-		}
198
-
199
-		// set device passwort
200
-		if (isset($devicepassword)) {
201
-			self::$encoder->startTag(SYNC_SETTINGS_DEVICEPW);
202
-			self::$encoder->startTag(SYNC_SETTINGS_SET);
203
-			self::$encoder->startTag(SYNC_SETTINGS_STATUS);
204
-			self::$encoder->content($devicepassword->Status);
205
-			self::$encoder->endTag(); // SYNC_SETTINGS_STATUS
206
-					self::$encoder->endTag(); // SYNC_SETTINGS_SET
207
-				self::$encoder->endTag(); // SYNC_SETTINGS_DEVICEPW
208
-		}
209
-
210
-		// set device information
211
-		if (isset($deviceinformation)) {
212
-			self::$encoder->startTag(SYNC_SETTINGS_DEVICEINFORMATION);
213
-			self::$encoder->startTag(SYNC_SETTINGS_STATUS);
214
-			self::$encoder->content($deviceinformation->Status);
215
-			self::$encoder->endTag(); // SYNC_SETTINGS_STATUS
216
-				self::$encoder->endTag(); // SYNC_SETTINGS_DEVICEINFORMATION
217
-		}
218
-
219
-		self::$encoder->endTag(); // SYNC_SETTINGS_SETTINGS
220
-
221
-		return true;
222
-	}
11
+    /**
12
+     * Handles the Settings command.
13
+     *
14
+     * @param int $commandCode
15
+     *
16
+     * @return bool
17
+     */
18
+    public function Handle($commandCode) {
19
+        if (!self::$decoder->getElementStartTag(SYNC_SETTINGS_SETTINGS)) {
20
+            return false;
21
+        }
22
+
23
+        // save the request parameters
24
+        $request = [];
25
+
26
+        // Loop through properties. Possible are:
27
+        // - Out of office
28
+        // - DevicePassword
29
+        // - DeviceInformation
30
+        // - UserInformation
31
+        // Each of them should only be once per request. Each property must be processed in order.
32
+        WBXMLDecoder::ResetInWhile("settingsMain");
33
+        while (WBXMLDecoder::InWhile("settingsMain")) {
34
+            $propertyName = "";
35
+            if (self::$decoder->getElementStartTag(SYNC_SETTINGS_OOF)) {
36
+                $propertyName = SYNC_SETTINGS_OOF;
37
+            }
38
+            if (self::$decoder->getElementStartTag(SYNC_SETTINGS_DEVICEPW)) {
39
+                $propertyName = SYNC_SETTINGS_DEVICEPW;
40
+            }
41
+            if (self::$decoder->getElementStartTag(SYNC_SETTINGS_DEVICEINFORMATION)) {
42
+                $propertyName = SYNC_SETTINGS_DEVICEINFORMATION;
43
+            }
44
+            if (self::$decoder->getElementStartTag(SYNC_SETTINGS_USERINFORMATION)) {
45
+                $propertyName = SYNC_SETTINGS_USERINFORMATION;
46
+            }
47
+            if (self::$decoder->getElementStartTag(SYNC_SETTINGS_RIGHTSMANAGEMENTINFORMATION)) {
48
+                $propertyName = SYNC_SETTINGS_RIGHTSMANAGEMENTINFORMATION;
49
+            }
50
+            // TODO - check if it is necessary
51
+            // no property name available - break
52
+            if (!$propertyName) {
53
+                break;
54
+            }
55
+
56
+            // the property name is followed by either get or set
57
+            if (self::$decoder->getElementStartTag(SYNC_SETTINGS_GET)) {
58
+                // get is available for OOF (AS 12), user information (AS 12) and rights management (AS 14.1)
59
+                switch ($propertyName) {
60
+                    case SYNC_SETTINGS_OOF:
61
+                        $oofGet = new SyncOOF();
62
+                        $oofGet->Decode(self::$decoder);
63
+                        if (!self::$decoder->getElementEndTag()) {
64
+                            return false;
65
+                        } // SYNC_SETTINGS_GET
66
+                        break;
67
+
68
+                    case SYNC_SETTINGS_USERINFORMATION:
69
+                        $userInformation = new SyncUserInformation();
70
+                        break;
71
+
72
+                    case SYNC_SETTINGS_RIGHTSMANAGEMENTINFORMATION:
73
+                        $rmTemplates = new SyncRightsManagementTemplates();
74
+                        break;
75
+
76
+                    default:
77
+                        // TODO: a special status code needed?
78
+                        SLog::Write(LOGLEVEL_WARN, sprintf("This property ('%s') is not allowed to use get in request", $propertyName));
79
+                }
80
+            }
81
+            elseif (self::$decoder->getElementStartTag(SYNC_SETTINGS_SET)) {
82
+                // set is available for OOF, device password and device information
83
+                switch ($propertyName) {
84
+                    case SYNC_SETTINGS_OOF:
85
+                        $oofSet = new SyncOOF();
86
+                        $oofSet->Decode(self::$decoder);
87
+                        // TODO check - do it after while(1) finished?
88
+                        break;
89
+
90
+                    case SYNC_SETTINGS_DEVICEPW:
91
+                        // TODO device password
92
+                        $devicepassword = new SyncDevicePassword();
93
+                        $devicepassword->Decode(self::$decoder);
94
+                        break;
95
+
96
+                    case SYNC_SETTINGS_DEVICEINFORMATION:
97
+                        $deviceinformation = new SyncDeviceInformation();
98
+                        $deviceinformation->Decode(self::$decoder);
99
+                        $deviceinformation->Status = SYNC_SETTINGSSTATUS_SUCCESS;
100
+                        self::$deviceManager->SaveDeviceInformation($deviceinformation);
101
+                        break;
102
+
103
+                    default:
104
+                        // TODO: a special status code needed?
105
+                        SLog::Write(LOGLEVEL_WARN, sprintf("This property ('%s') is not allowed to use set in request", $propertyName));
106
+                }
107
+
108
+                if (!self::$decoder->getElementEndTag()) {
109
+                    return false;
110
+                } // SYNC_SETTINGS_SET
111
+            }
112
+            else {
113
+                SLog::Write(LOGLEVEL_WARN, sprintf("Neither get nor set found for property '%s'", $propertyName));
114
+
115
+                return false;
116
+            }
117
+
118
+            if (!self::$decoder->getElementEndTag()) {
119
+                return false;
120
+            } // SYNC_SETTINGS_OOF or SYNC_SETTINGS_DEVICEPW or SYNC_SETTINGS_DEVICEINFORMATION or SYNC_SETTINGS_USERINFORMATION
121
+
122
+            // break if it reached the endtag
123
+            $e = self::$decoder->peek();
124
+            if ($e[EN_TYPE] == EN_TYPE_ENDTAG) {
125
+                self::$decoder->getElementEndTag(); // SYNC_SETTINGS_SETTINGS
126
+
127
+                break;
128
+            }
129
+        }
130
+
131
+        $status = SYNC_SETTINGSSTATUS_SUCCESS;
132
+
133
+        // TODO put it in try catch block
134
+        // TODO implement Settings in the backend
135
+        // TODO save device information in device manager
136
+        // TODO status handling
137
+        //        $data = self::$backend->Settings($request);
138
+
139
+        self::$encoder->startWBXML();
140
+        self::$encoder->startTag(SYNC_SETTINGS_SETTINGS);
141
+
142
+        self::$encoder->startTag(SYNC_SETTINGS_STATUS);
143
+        self::$encoder->content($status);
144
+        self::$encoder->endTag(); // SYNC_SETTINGS_STATUS
145
+
146
+        // get oof settings
147
+        if (isset($oofGet)) {
148
+            $oofGet = self::$backend->Settings($oofGet);
149
+            self::$encoder->startTag(SYNC_SETTINGS_OOF);
150
+            self::$encoder->startTag(SYNC_SETTINGS_STATUS);
151
+            self::$encoder->content($oofGet->Status);
152
+            self::$encoder->endTag(); // SYNC_SETTINGS_STATUS
153
+
154
+            self::$encoder->startTag(SYNC_SETTINGS_GET);
155
+            $oofGet->Encode(self::$encoder);
156
+            self::$encoder->endTag(); // SYNC_SETTINGS_GET
157
+                self::$encoder->endTag(); // SYNC_SETTINGS_OOF
158
+        }
159
+
160
+        // get user information
161
+        // TODO none email address found
162
+        if (isset($userInformation)) {
163
+            self::$backend->Settings($userInformation);
164
+            self::$encoder->startTag(SYNC_SETTINGS_USERINFORMATION);
165
+            self::$encoder->startTag(SYNC_SETTINGS_STATUS);
166
+            self::$encoder->content($userInformation->Status);
167
+            self::$encoder->endTag(); // SYNC_SETTINGS_STATUS
168
+
169
+            self::$encoder->startTag(SYNC_SETTINGS_GET);
170
+            $userInformation->Encode(self::$encoder);
171
+            self::$encoder->endTag(); // SYNC_SETTINGS_GET
172
+                self::$encoder->endTag(); // SYNC_SETTINGS_USERINFORMATION
173
+        }
174
+
175
+        // get rights management templates
176
+        if (isset($rmTemplates)) {
177
+            self::$backend->Settings($rmTemplates);
178
+            self::$encoder->startTag(SYNC_SETTINGS_RIGHTSMANAGEMENTINFORMATION);
179
+            self::$encoder->startTag(SYNC_SETTINGS_STATUS);
180
+            self::$encoder->content($rmTemplates->Status);
181
+            self::$encoder->endTag(); // SYNC_SETTINGS_STATUS
182
+
183
+            self::$encoder->startTag(SYNC_SETTINGS_GET);
184
+            $rmTemplates->Encode(self::$encoder);
185
+            self::$encoder->endTag(); // SYNC_SETTINGS_GET
186
+                self::$encoder->endTag(); // SYNC_SETTINGS_RIGHTSMANAGEMENTINFORMATION
187
+        }
188
+
189
+        // set out of office
190
+        if (isset($oofSet)) {
191
+            $oofSet = self::$backend->Settings($oofSet);
192
+            self::$encoder->startTag(SYNC_SETTINGS_OOF);
193
+            self::$encoder->startTag(SYNC_SETTINGS_STATUS);
194
+            self::$encoder->content($oofSet->Status);
195
+            self::$encoder->endTag(); // SYNC_SETTINGS_STATUS
196
+                self::$encoder->endTag(); // SYNC_SETTINGS_OOF
197
+        }
198
+
199
+        // set device passwort
200
+        if (isset($devicepassword)) {
201
+            self::$encoder->startTag(SYNC_SETTINGS_DEVICEPW);
202
+            self::$encoder->startTag(SYNC_SETTINGS_SET);
203
+            self::$encoder->startTag(SYNC_SETTINGS_STATUS);
204
+            self::$encoder->content($devicepassword->Status);
205
+            self::$encoder->endTag(); // SYNC_SETTINGS_STATUS
206
+                    self::$encoder->endTag(); // SYNC_SETTINGS_SET
207
+                self::$encoder->endTag(); // SYNC_SETTINGS_DEVICEPW
208
+        }
209
+
210
+        // set device information
211
+        if (isset($deviceinformation)) {
212
+            self::$encoder->startTag(SYNC_SETTINGS_DEVICEINFORMATION);
213
+            self::$encoder->startTag(SYNC_SETTINGS_STATUS);
214
+            self::$encoder->content($deviceinformation->Status);
215
+            self::$encoder->endTag(); // SYNC_SETTINGS_STATUS
216
+                self::$encoder->endTag(); // SYNC_SETTINGS_DEVICEINFORMATION
217
+        }
218
+
219
+        self::$encoder->endTag(); // SYNC_SETTINGS_SETTINGS
220
+
221
+        return true;
222
+    }
223 223
 }
Please login to merge, or discard this patch.
Braces   +2 added lines, -4 removed lines patch added patch discarded remove patch
@@ -77,8 +77,7 @@  discard block
 block discarded – undo
77 77
 						// TODO: a special status code needed?
78 78
 						SLog::Write(LOGLEVEL_WARN, sprintf("This property ('%s') is not allowed to use get in request", $propertyName));
79 79
 				}
80
-			}
81
-			elseif (self::$decoder->getElementStartTag(SYNC_SETTINGS_SET)) {
80
+			} elseif (self::$decoder->getElementStartTag(SYNC_SETTINGS_SET)) {
82 81
 				// set is available for OOF, device password and device information
83 82
 				switch ($propertyName) {
84 83
 					case SYNC_SETTINGS_OOF:
@@ -108,8 +107,7 @@  discard block
 block discarded – undo
108 107
 				if (!self::$decoder->getElementEndTag()) {
109 108
 					return false;
110 109
 				} // SYNC_SETTINGS_SET
111
-			}
112
-			else {
110
+			} else {
113 111
 				SLog::Write(LOGLEVEL_WARN, sprintf("Neither get nor set found for property '%s'", $propertyName));
114 112
 
115 113
 				return false;
Please login to merge, or discard this patch.
lib/request/gethierarchy.php 2 patches
Indentation   +30 added lines, -30 removed lines patch added patch discarded remove patch
@@ -8,37 +8,37 @@
 block discarded – undo
8 8
  */
9 9
 
10 10
 class GetHierarchy extends RequestProcessor {
11
-	/**
12
-	 * Handles the GetHierarchy command
13
-	 * simply returns current hierarchy of all folders.
14
-	 *
15
-	 * @param int $commandCode
16
-	 *
17
-	 * @return bool
18
-	 */
19
-	public function Handle($commandCode) {
20
-		try {
21
-			$folders = self::$backend->GetHierarchy();
22
-			if (!$folders || empty($folders)) {
23
-				throw new StatusException("GetHierarchy() did not return any data.");
24
-			}
11
+    /**
12
+     * Handles the GetHierarchy command
13
+     * simply returns current hierarchy of all folders.
14
+     *
15
+     * @param int $commandCode
16
+     *
17
+     * @return bool
18
+     */
19
+    public function Handle($commandCode) {
20
+        try {
21
+            $folders = self::$backend->GetHierarchy();
22
+            if (!$folders || empty($folders)) {
23
+                throw new StatusException("GetHierarchy() did not return any data.");
24
+            }
25 25
 
26
-			// TODO execute $data->Check() to see if SyncObject is valid
27
-		}
28
-		catch (StatusException $ex) {
29
-			return false;
30
-		}
26
+            // TODO execute $data->Check() to see if SyncObject is valid
27
+        }
28
+        catch (StatusException $ex) {
29
+            return false;
30
+        }
31 31
 
32
-		self::$encoder->StartWBXML();
33
-		self::$encoder->startTag(SYNC_FOLDERHIERARCHY_FOLDERS);
34
-		foreach ($folders as $folder) {
35
-			self::$encoder->startTag(SYNC_FOLDERHIERARCHY_FOLDER);
36
-			$folder->Encode(self::$encoder);
37
-			self::$encoder->endTag();
38
-		}
39
-		self::$encoder->endTag();
32
+        self::$encoder->StartWBXML();
33
+        self::$encoder->startTag(SYNC_FOLDERHIERARCHY_FOLDERS);
34
+        foreach ($folders as $folder) {
35
+            self::$encoder->startTag(SYNC_FOLDERHIERARCHY_FOLDER);
36
+            $folder->Encode(self::$encoder);
37
+            self::$encoder->endTag();
38
+        }
39
+        self::$encoder->endTag();
40 40
 
41
-		// save hierarchy for upcoming syncing
42
-		return self::$deviceManager->InitializeFolderCache($folders);
43
-	}
41
+        // save hierarchy for upcoming syncing
42
+        return self::$deviceManager->InitializeFolderCache($folders);
43
+    }
44 44
 }
Please login to merge, or discard this patch.
Braces   +1 added lines, -2 removed lines patch added patch discarded remove patch
@@ -24,8 +24,7 @@
 block discarded – undo
24 24
 			}
25 25
 
26 26
 			// TODO execute $data->Check() to see if SyncObject is valid
27
-		}
28
-		catch (StatusException $ex) {
27
+		} catch (StatusException $ex) {
29 28
 			return false;
30 29
 		}
31 30
 
Please login to merge, or discard this patch.
lib/request/foldersync.php 2 patches
Indentation   +253 added lines, -253 removed lines patch added patch discarded remove patch
@@ -8,257 +8,257 @@
 block discarded – undo
8 8
  */
9 9
 
10 10
 class FolderSync extends RequestProcessor {
11
-	/**
12
-	 * Handles the FolderSync 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_FOLDERHIERARCHY_FOLDERSYNC)) {
21
-			return false;
22
-		}
23
-
24
-		if (!self::$decoder->getElementStartTag(SYNC_FOLDERHIERARCHY_SYNCKEY)) {
25
-			return false;
26
-		}
27
-
28
-		$synckey = self::$decoder->getElementContent();
29
-
30
-		if (!self::$decoder->getElementEndTag()) {
31
-			return false;
32
-		}
33
-
34
-		// every FolderSync with SyncKey 0 should return the supported AS version & command headers
35
-		if ($synckey == "0") {
36
-			self::$specialHeaders = [];
37
-			self::$specialHeaders[] = GSync::GetSupportedProtocolVersions();
38
-			self::$specialHeaders[] = GSync::GetSupportedCommands();
39
-		}
40
-
41
-		$status = SYNC_FSSTATUS_SUCCESS;
42
-		$newsynckey = $synckey;
43
-
44
-		try {
45
-			$syncstate = self::$deviceManager->GetStateManager()->GetSyncState($synckey);
46
-
47
-			// We will be saving the sync state under 'newsynckey'
48
-			$newsynckey = self::$deviceManager->GetStateManager()->GetNewSyncKey($synckey);
49
-
50
-			// there are no SyncParameters for the hierarchy, but we use it to save the latest synckeys
51
-			$spa = self::$deviceManager->GetStateManager()->GetSynchedFolderState(false);
52
-		}
53
-		catch (StateNotFoundException $snfex) {
54
-			$status = SYNC_FSSTATUS_SYNCKEYERROR;
55
-		}
56
-		catch (StateInvalidException $sive) {
57
-			$status = SYNC_FSSTATUS_SYNCKEYERROR;
58
-		}
59
-
60
-		// The ChangesWrapper caches all imports in-memory, so we can send a change count
61
-		// before sending the actual data.
62
-		// the HierarchyCache is notified and the changes from the PIM are transmitted to the actual backend
63
-		$changesMem = self::$deviceManager->GetHierarchyChangesWrapper();
64
-
65
-		// the hierarchyCache should now fully be initialized - check for changes in the additional folders
66
-		$changesMem->Config(GSync::GetAdditionalSyncFolders(false), ChangesMemoryWrapper::SYNCHRONIZING);
67
-
68
-		// reset to default store in backend
69
-		self::$backend->Setup(false);
70
-
71
-		// process incoming changes
72
-		if (self::$decoder->getElementStartTag(SYNC_FOLDERHIERARCHY_CHANGES)) {
73
-			// Ignore <Count> if present
74
-			if (self::$decoder->getElementStartTag(SYNC_FOLDERHIERARCHY_COUNT)) {
75
-				self::$decoder->getElementContent();
76
-				if (!self::$decoder->getElementEndTag()) {
77
-					return false;
78
-				}
79
-			}
80
-
81
-			// Process the changes (either <Add>, <Modify>, or <Remove>)
82
-			$element = self::$decoder->getElement();
83
-
84
-			if ($element[EN_TYPE] != EN_TYPE_STARTTAG) {
85
-				return false;
86
-			}
87
-
88
-			$importer = false;
89
-			WBXMLDecoder::ResetInWhile("folderSyncIncomingChange");
90
-			while (WBXMLDecoder::InWhile("folderSyncIncomingChange")) {
91
-				$folder = new SyncFolder();
92
-				if (!$folder->Decode(self::$decoder)) {
93
-					break;
94
-				}
95
-
96
-				// add the backendId to the SyncFolder object
97
-				$folder->BackendId = self::$deviceManager->GetBackendIdForFolderId($folder->serverid);
98
-
99
-				try {
100
-					if ($status == SYNC_FSSTATUS_SUCCESS && !$importer) {
101
-						// Configure the backends importer with last state
102
-						$importer = self::$backend->GetImporter();
103
-						$importer->Config($syncstate);
104
-						// the messages from the PIM will be forwarded to the backend
105
-						$changesMem->forwardImporter($importer);
106
-					}
107
-
108
-					if ($status == SYNC_FSSTATUS_SUCCESS) {
109
-						switch ($element[EN_TAG]) {
110
-							case SYNC_ADD:
111
-							case SYNC_MODIFY:
112
-								$serverid = $changesMem->ImportFolderChange($folder);
113
-								break;
114
-
115
-							case SYNC_REMOVE:
116
-								$serverid = $changesMem->ImportFolderDeletion($folder);
117
-								break;
118
-						}
119
-					}
120
-					else {
121
-						SLog::Write(LOGLEVEL_WARN, sprintf("Request->HandleFolderSync(): ignoring incoming folderchange for folder '%s' as status indicates problem.", $folder->displayname));
122
-						self::$topCollector->AnnounceInformation("Incoming change ignored", true);
123
-					}
124
-				}
125
-				catch (StatusException $stex) {
126
-					$status = $stex->getCode();
127
-				}
128
-			}
129
-
130
-			if (!self::$decoder->getElementEndTag()) {
131
-				return false;
132
-			}
133
-		}
134
-		// no incoming changes
135
-		else {
136
-			// check for a potential process loop like described in Issue ZP-5
137
-			if ($synckey != "0" && self::$deviceManager->IsHierarchyFullResyncRequired()) {
138
-				$status = SYNC_FSSTATUS_SYNCKEYERROR;
139
-				self::$deviceManager->AnnounceProcessStatus(false, $status);
140
-			}
141
-		}
142
-
143
-		if (!self::$decoder->getElementEndTag()) {
144
-			return false;
145
-		}
146
-
147
-		// We have processed incoming foldersync requests, now send the PIM
148
-		// our changes
149
-
150
-		// Output our WBXML reply now
151
-		self::$encoder->StartWBXML();
152
-
153
-		self::$encoder->startTag(SYNC_FOLDERHIERARCHY_FOLDERSYNC);
154
-
155
-		if ($status == SYNC_FSSTATUS_SUCCESS) {
156
-			try {
157
-				// do nothing if this is an invalid device id (like the 'validate' Androids internal client sends)
158
-				if (!Request::IsValidDeviceID()) {
159
-					throw new StatusException(sprintf("Request::IsValidDeviceID() indicated that '%s' is not a valid device id", Request::GetDeviceID()), SYNC_FSSTATUS_SERVERERROR);
160
-				}
161
-
162
-				// Changes from backend are sent to the MemImporter and processed for the HierarchyCache.
163
-				// The state which is saved is from the backend, as the MemImporter is only a proxy.
164
-				$exporter = self::$backend->GetExporter();
165
-
166
-				$exporter->Config($syncstate);
167
-				$exporter->InitializeExporter($changesMem);
168
-
169
-				// Stream all changes to the ImportExportChangesMem
170
-				$totalChanges = $exporter->GetChangeCount();
171
-				$exported = 0;
172
-				$partial = false;
173
-				while (is_array($exporter->Synchronize())) {
174
-					++$exported;
175
-
176
-					if (time() % 4) {
177
-						self::$topCollector->AnnounceInformation(sprintf("Exported %d from %d folders", $exported, $totalChanges));
178
-					}
179
-
180
-					// if partial sync is allowed, stop if this takes too long
181
-					if (USE_PARTIAL_FOLDERSYNC && Request::IsRequestTimeoutReached()) {
182
-						SLog::Write(LOGLEVEL_WARN, sprintf("Request->HandleFolderSync(): Exporting folders is too slow. In %d seconds only %d from %d changes were processed.", (time() - $_SERVER["REQUEST_TIME"]), $exported, $totalChanges));
183
-						self::$topCollector->AnnounceInformation(sprintf("Partial export of %d out of %d folders", $exported, $totalChanges), true);
184
-						self::$deviceManager->SetFolderSyncComplete(false);
185
-						$partial = true;
186
-
187
-						break;
188
-					}
189
-				}
190
-
191
-				// update the foldersync complete flag
192
-				if (USE_PARTIAL_FOLDERSYNC && $partial == false && self::$deviceManager->GetFolderSyncComplete() === false) {
193
-					// say that we are done with partial syncing
194
-					self::$deviceManager->SetFolderSyncComplete(true);
195
-					// reset the loop data to prevent any loop detection to kick in now
196
-					self::$deviceManager->ClearLoopDetectionData(Request::GetAuthUserString(), Request::GetDeviceID());
197
-					SLog::Write(LOGLEVEL_INFO, "Request->HandleFolderSync(): Chunked exporting of folders completed successfully");
198
-				}
199
-
200
-				// get the new state from the backend
201
-				$newsyncstate = (isset($exporter)) ? $exporter->GetState() : "";
202
-			}
203
-			catch (StatusException $stex) {
204
-				if ($stex->getCode() == SYNC_FSSTATUS_CODEUNKNOWN) {
205
-					$status = SYNC_FSSTATUS_SYNCKEYERROR;
206
-				}
207
-				else {
208
-					$status = $stex->getCode();
209
-				}
210
-			}
211
-		}
212
-
213
-		self::$encoder->startTag(SYNC_FOLDERHIERARCHY_STATUS);
214
-		self::$encoder->content($status);
215
-		self::$encoder->endTag();
216
-
217
-		if ($status == SYNC_FSSTATUS_SUCCESS) {
218
-			self::$encoder->startTag(SYNC_FOLDERHIERARCHY_SYNCKEY);
219
-			$synckey = ($changesMem->IsStateChanged()) ? $newsynckey : $synckey;
220
-			self::$encoder->content($synckey);
221
-			self::$encoder->endTag();
222
-
223
-			// Stream folders directly to the PDA
224
-			$streamimporter = new ImportChangesStream(self::$encoder, false);
225
-			$changesMem->InitializeExporter($streamimporter);
226
-			$changeCount = $changesMem->GetChangeCount();
227
-
228
-			self::$encoder->startTag(SYNC_FOLDERHIERARCHY_CHANGES);
229
-
230
-			self::$encoder->startTag(SYNC_FOLDERHIERARCHY_COUNT);
231
-			self::$encoder->content($changeCount);
232
-			self::$encoder->endTag();
233
-			while ($changesMem->Synchronize());
234
-
235
-			self::$encoder->endTag();
236
-			self::$topCollector->AnnounceInformation(sprintf("Outgoing %d folders", $changeCount), true);
237
-
238
-			if ($changeCount == 0) {
239
-				self::$deviceManager->CheckFolderData();
240
-			}
241
-			// everything fine, save the sync state for the next time
242
-			if ($synckey == $newsynckey) {
243
-				self::$deviceManager->GetStateManager()->SetSyncState($newsynckey, $newsyncstate);
244
-
245
-				// update SPA & save it
246
-				$spa->SetSyncKey($newsynckey);
247
-				$spa->SetFolderId(false);
248
-
249
-				// invalidate all pingable flags
250
-				SyncCollections::InvalidatePingableFlags();
251
-			}
252
-			// save the SyncParameters if it changed or the reference policy key is not set or different
253
-			if ($spa->IsDataChanged() || !$spa->HasReferencePolicyKey() || GSync::GetProvisioningManager()->ProvisioningRequired($spa->GetReferencePolicyKey(), true, false)) {
254
-				// saves the SPA (while updating the reference policy key)
255
-				$spa->SetLastSynctime(time());
256
-				self::$deviceManager->GetStateManager()->SetSynchedFolderState($spa);
257
-			}
258
-		}
259
-
260
-		self::$encoder->endTag();
261
-
262
-		return true;
263
-	}
11
+    /**
12
+     * Handles the FolderSync 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_FOLDERHIERARCHY_FOLDERSYNC)) {
21
+            return false;
22
+        }
23
+
24
+        if (!self::$decoder->getElementStartTag(SYNC_FOLDERHIERARCHY_SYNCKEY)) {
25
+            return false;
26
+        }
27
+
28
+        $synckey = self::$decoder->getElementContent();
29
+
30
+        if (!self::$decoder->getElementEndTag()) {
31
+            return false;
32
+        }
33
+
34
+        // every FolderSync with SyncKey 0 should return the supported AS version & command headers
35
+        if ($synckey == "0") {
36
+            self::$specialHeaders = [];
37
+            self::$specialHeaders[] = GSync::GetSupportedProtocolVersions();
38
+            self::$specialHeaders[] = GSync::GetSupportedCommands();
39
+        }
40
+
41
+        $status = SYNC_FSSTATUS_SUCCESS;
42
+        $newsynckey = $synckey;
43
+
44
+        try {
45
+            $syncstate = self::$deviceManager->GetStateManager()->GetSyncState($synckey);
46
+
47
+            // We will be saving the sync state under 'newsynckey'
48
+            $newsynckey = self::$deviceManager->GetStateManager()->GetNewSyncKey($synckey);
49
+
50
+            // there are no SyncParameters for the hierarchy, but we use it to save the latest synckeys
51
+            $spa = self::$deviceManager->GetStateManager()->GetSynchedFolderState(false);
52
+        }
53
+        catch (StateNotFoundException $snfex) {
54
+            $status = SYNC_FSSTATUS_SYNCKEYERROR;
55
+        }
56
+        catch (StateInvalidException $sive) {
57
+            $status = SYNC_FSSTATUS_SYNCKEYERROR;
58
+        }
59
+
60
+        // The ChangesWrapper caches all imports in-memory, so we can send a change count
61
+        // before sending the actual data.
62
+        // the HierarchyCache is notified and the changes from the PIM are transmitted to the actual backend
63
+        $changesMem = self::$deviceManager->GetHierarchyChangesWrapper();
64
+
65
+        // the hierarchyCache should now fully be initialized - check for changes in the additional folders
66
+        $changesMem->Config(GSync::GetAdditionalSyncFolders(false), ChangesMemoryWrapper::SYNCHRONIZING);
67
+
68
+        // reset to default store in backend
69
+        self::$backend->Setup(false);
70
+
71
+        // process incoming changes
72
+        if (self::$decoder->getElementStartTag(SYNC_FOLDERHIERARCHY_CHANGES)) {
73
+            // Ignore <Count> if present
74
+            if (self::$decoder->getElementStartTag(SYNC_FOLDERHIERARCHY_COUNT)) {
75
+                self::$decoder->getElementContent();
76
+                if (!self::$decoder->getElementEndTag()) {
77
+                    return false;
78
+                }
79
+            }
80
+
81
+            // Process the changes (either <Add>, <Modify>, or <Remove>)
82
+            $element = self::$decoder->getElement();
83
+
84
+            if ($element[EN_TYPE] != EN_TYPE_STARTTAG) {
85
+                return false;
86
+            }
87
+
88
+            $importer = false;
89
+            WBXMLDecoder::ResetInWhile("folderSyncIncomingChange");
90
+            while (WBXMLDecoder::InWhile("folderSyncIncomingChange")) {
91
+                $folder = new SyncFolder();
92
+                if (!$folder->Decode(self::$decoder)) {
93
+                    break;
94
+                }
95
+
96
+                // add the backendId to the SyncFolder object
97
+                $folder->BackendId = self::$deviceManager->GetBackendIdForFolderId($folder->serverid);
98
+
99
+                try {
100
+                    if ($status == SYNC_FSSTATUS_SUCCESS && !$importer) {
101
+                        // Configure the backends importer with last state
102
+                        $importer = self::$backend->GetImporter();
103
+                        $importer->Config($syncstate);
104
+                        // the messages from the PIM will be forwarded to the backend
105
+                        $changesMem->forwardImporter($importer);
106
+                    }
107
+
108
+                    if ($status == SYNC_FSSTATUS_SUCCESS) {
109
+                        switch ($element[EN_TAG]) {
110
+                            case SYNC_ADD:
111
+                            case SYNC_MODIFY:
112
+                                $serverid = $changesMem->ImportFolderChange($folder);
113
+                                break;
114
+
115
+                            case SYNC_REMOVE:
116
+                                $serverid = $changesMem->ImportFolderDeletion($folder);
117
+                                break;
118
+                        }
119
+                    }
120
+                    else {
121
+                        SLog::Write(LOGLEVEL_WARN, sprintf("Request->HandleFolderSync(): ignoring incoming folderchange for folder '%s' as status indicates problem.", $folder->displayname));
122
+                        self::$topCollector->AnnounceInformation("Incoming change ignored", true);
123
+                    }
124
+                }
125
+                catch (StatusException $stex) {
126
+                    $status = $stex->getCode();
127
+                }
128
+            }
129
+
130
+            if (!self::$decoder->getElementEndTag()) {
131
+                return false;
132
+            }
133
+        }
134
+        // no incoming changes
135
+        else {
136
+            // check for a potential process loop like described in Issue ZP-5
137
+            if ($synckey != "0" && self::$deviceManager->IsHierarchyFullResyncRequired()) {
138
+                $status = SYNC_FSSTATUS_SYNCKEYERROR;
139
+                self::$deviceManager->AnnounceProcessStatus(false, $status);
140
+            }
141
+        }
142
+
143
+        if (!self::$decoder->getElementEndTag()) {
144
+            return false;
145
+        }
146
+
147
+        // We have processed incoming foldersync requests, now send the PIM
148
+        // our changes
149
+
150
+        // Output our WBXML reply now
151
+        self::$encoder->StartWBXML();
152
+
153
+        self::$encoder->startTag(SYNC_FOLDERHIERARCHY_FOLDERSYNC);
154
+
155
+        if ($status == SYNC_FSSTATUS_SUCCESS) {
156
+            try {
157
+                // do nothing if this is an invalid device id (like the 'validate' Androids internal client sends)
158
+                if (!Request::IsValidDeviceID()) {
159
+                    throw new StatusException(sprintf("Request::IsValidDeviceID() indicated that '%s' is not a valid device id", Request::GetDeviceID()), SYNC_FSSTATUS_SERVERERROR);
160
+                }
161
+
162
+                // Changes from backend are sent to the MemImporter and processed for the HierarchyCache.
163
+                // The state which is saved is from the backend, as the MemImporter is only a proxy.
164
+                $exporter = self::$backend->GetExporter();
165
+
166
+                $exporter->Config($syncstate);
167
+                $exporter->InitializeExporter($changesMem);
168
+
169
+                // Stream all changes to the ImportExportChangesMem
170
+                $totalChanges = $exporter->GetChangeCount();
171
+                $exported = 0;
172
+                $partial = false;
173
+                while (is_array($exporter->Synchronize())) {
174
+                    ++$exported;
175
+
176
+                    if (time() % 4) {
177
+                        self::$topCollector->AnnounceInformation(sprintf("Exported %d from %d folders", $exported, $totalChanges));
178
+                    }
179
+
180
+                    // if partial sync is allowed, stop if this takes too long
181
+                    if (USE_PARTIAL_FOLDERSYNC && Request::IsRequestTimeoutReached()) {
182
+                        SLog::Write(LOGLEVEL_WARN, sprintf("Request->HandleFolderSync(): Exporting folders is too slow. In %d seconds only %d from %d changes were processed.", (time() - $_SERVER["REQUEST_TIME"]), $exported, $totalChanges));
183
+                        self::$topCollector->AnnounceInformation(sprintf("Partial export of %d out of %d folders", $exported, $totalChanges), true);
184
+                        self::$deviceManager->SetFolderSyncComplete(false);
185
+                        $partial = true;
186
+
187
+                        break;
188
+                    }
189
+                }
190
+
191
+                // update the foldersync complete flag
192
+                if (USE_PARTIAL_FOLDERSYNC && $partial == false && self::$deviceManager->GetFolderSyncComplete() === false) {
193
+                    // say that we are done with partial syncing
194
+                    self::$deviceManager->SetFolderSyncComplete(true);
195
+                    // reset the loop data to prevent any loop detection to kick in now
196
+                    self::$deviceManager->ClearLoopDetectionData(Request::GetAuthUserString(), Request::GetDeviceID());
197
+                    SLog::Write(LOGLEVEL_INFO, "Request->HandleFolderSync(): Chunked exporting of folders completed successfully");
198
+                }
199
+
200
+                // get the new state from the backend
201
+                $newsyncstate = (isset($exporter)) ? $exporter->GetState() : "";
202
+            }
203
+            catch (StatusException $stex) {
204
+                if ($stex->getCode() == SYNC_FSSTATUS_CODEUNKNOWN) {
205
+                    $status = SYNC_FSSTATUS_SYNCKEYERROR;
206
+                }
207
+                else {
208
+                    $status = $stex->getCode();
209
+                }
210
+            }
211
+        }
212
+
213
+        self::$encoder->startTag(SYNC_FOLDERHIERARCHY_STATUS);
214
+        self::$encoder->content($status);
215
+        self::$encoder->endTag();
216
+
217
+        if ($status == SYNC_FSSTATUS_SUCCESS) {
218
+            self::$encoder->startTag(SYNC_FOLDERHIERARCHY_SYNCKEY);
219
+            $synckey = ($changesMem->IsStateChanged()) ? $newsynckey : $synckey;
220
+            self::$encoder->content($synckey);
221
+            self::$encoder->endTag();
222
+
223
+            // Stream folders directly to the PDA
224
+            $streamimporter = new ImportChangesStream(self::$encoder, false);
225
+            $changesMem->InitializeExporter($streamimporter);
226
+            $changeCount = $changesMem->GetChangeCount();
227
+
228
+            self::$encoder->startTag(SYNC_FOLDERHIERARCHY_CHANGES);
229
+
230
+            self::$encoder->startTag(SYNC_FOLDERHIERARCHY_COUNT);
231
+            self::$encoder->content($changeCount);
232
+            self::$encoder->endTag();
233
+            while ($changesMem->Synchronize());
234
+
235
+            self::$encoder->endTag();
236
+            self::$topCollector->AnnounceInformation(sprintf("Outgoing %d folders", $changeCount), true);
237
+
238
+            if ($changeCount == 0) {
239
+                self::$deviceManager->CheckFolderData();
240
+            }
241
+            // everything fine, save the sync state for the next time
242
+            if ($synckey == $newsynckey) {
243
+                self::$deviceManager->GetStateManager()->SetSyncState($newsynckey, $newsyncstate);
244
+
245
+                // update SPA & save it
246
+                $spa->SetSyncKey($newsynckey);
247
+                $spa->SetFolderId(false);
248
+
249
+                // invalidate all pingable flags
250
+                SyncCollections::InvalidatePingableFlags();
251
+            }
252
+            // save the SyncParameters if it changed or the reference policy key is not set or different
253
+            if ($spa->IsDataChanged() || !$spa->HasReferencePolicyKey() || GSync::GetProvisioningManager()->ProvisioningRequired($spa->GetReferencePolicyKey(), true, false)) {
254
+                // saves the SPA (while updating the reference policy key)
255
+                $spa->SetLastSynctime(time());
256
+                self::$deviceManager->GetStateManager()->SetSynchedFolderState($spa);
257
+            }
258
+        }
259
+
260
+        self::$encoder->endTag();
261
+
262
+        return true;
263
+    }
264 264
 }
Please login to merge, or discard this patch.
Braces   +6 added lines, -12 removed lines patch added patch discarded remove patch
@@ -49,11 +49,9 @@  discard block
 block discarded – undo
49 49
 
50 50
 			// there are no SyncParameters for the hierarchy, but we use it to save the latest synckeys
51 51
 			$spa = self::$deviceManager->GetStateManager()->GetSynchedFolderState(false);
52
-		}
53
-		catch (StateNotFoundException $snfex) {
52
+		} catch (StateNotFoundException $snfex) {
54 53
 			$status = SYNC_FSSTATUS_SYNCKEYERROR;
55
-		}
56
-		catch (StateInvalidException $sive) {
54
+		} catch (StateInvalidException $sive) {
57 55
 			$status = SYNC_FSSTATUS_SYNCKEYERROR;
58 56
 		}
59 57
 
@@ -116,13 +114,11 @@  discard block
 block discarded – undo
116 114
 								$serverid = $changesMem->ImportFolderDeletion($folder);
117 115
 								break;
118 116
 						}
119
-					}
120
-					else {
117
+					} else {
121 118
 						SLog::Write(LOGLEVEL_WARN, sprintf("Request->HandleFolderSync(): ignoring incoming folderchange for folder '%s' as status indicates problem.", $folder->displayname));
122 119
 						self::$topCollector->AnnounceInformation("Incoming change ignored", true);
123 120
 					}
124
-				}
125
-				catch (StatusException $stex) {
121
+				} catch (StatusException $stex) {
126 122
 					$status = $stex->getCode();
127 123
 				}
128 124
 			}
@@ -199,12 +195,10 @@  discard block
 block discarded – undo
199 195
 
200 196
 				// get the new state from the backend
201 197
 				$newsyncstate = (isset($exporter)) ? $exporter->GetState() : "";
202
-			}
203
-			catch (StatusException $stex) {
198
+			} catch (StatusException $stex) {
204 199
 				if ($stex->getCode() == SYNC_FSSTATUS_CODEUNKNOWN) {
205 200
 					$status = SYNC_FSSTATUS_SYNCKEYERROR;
206
-				}
207
-				else {
201
+				} else {
208 202
 					$status = $stex->getCode();
209 203
 				}
210 204
 			}
Please login to merge, or discard this patch.
lib/request/folderchange.php 2 patches
Indentation   +234 added lines, -234 removed lines patch added patch discarded remove patch
@@ -8,238 +8,238 @@
 block discarded – undo
8 8
  */
9 9
 
10 10
 class FolderChange extends RequestProcessor {
11
-	/**
12
-	 * Handles creates, updates or deletes of a folder
13
-	 * issued by the commands FolderCreate, FolderUpdate and FolderDelete.
14
-	 *
15
-	 * @param int $commandCode
16
-	 *
17
-	 * @return bool
18
-	 */
19
-	public function Handle($commandCode) {
20
-		$el = self::$decoder->getElement();
21
-
22
-		if ($el[EN_TYPE] != EN_TYPE_STARTTAG) {
23
-			return false;
24
-		}
25
-
26
-		$create = $update = $delete = false;
27
-		if ($el[EN_TAG] == SYNC_FOLDERHIERARCHY_FOLDERCREATE) {
28
-			$create = true;
29
-		}
30
-		elseif ($el[EN_TAG] == SYNC_FOLDERHIERARCHY_FOLDERUPDATE) {
31
-			$update = true;
32
-		}
33
-		elseif ($el[EN_TAG] == SYNC_FOLDERHIERARCHY_FOLDERDELETE) {
34
-			$delete = true;
35
-		}
36
-
37
-		if (!$create && !$update && !$delete) {
38
-			return false;
39
-		}
40
-
41
-		// SyncKey
42
-		if (!self::$decoder->getElementStartTag(SYNC_FOLDERHIERARCHY_SYNCKEY)) {
43
-			return false;
44
-		}
45
-		$synckey = self::$decoder->getElementContent();
46
-		if (!self::$decoder->getElementEndTag()) {
47
-			return false;
48
-		}
49
-
50
-		// ServerID
51
-		$serverid = false;
52
-		$backendid = false;
53
-		if (self::$decoder->getElementStartTag(SYNC_FOLDERHIERARCHY_SERVERENTRYID)) {
54
-			$serverid = self::$decoder->getElementContent();
55
-			$backendid = self::$deviceManager->GetBackendIdForFolderId($serverid);
56
-			if (!self::$decoder->getElementEndTag()) {
57
-				return false;
58
-			}
59
-		}
60
-
61
-		// Parent
62
-		$parentid = false;
63
-		$parentBackendId = false;
64
-
65
-		// when creating or updating more information is necessary
66
-		if (!$delete) {
67
-			if (self::$decoder->getElementStartTag(SYNC_FOLDERHIERARCHY_PARENTID)) {
68
-				$parentid = self::$decoder->getElementContent();
69
-				$parentBackendId = self::$deviceManager->GetBackendIdForFolderId($parentid);
70
-				if (!self::$decoder->getElementEndTag()) {
71
-					return false;
72
-				}
73
-			}
74
-
75
-			// Displayname
76
-			if (!self::$decoder->getElementStartTag(SYNC_FOLDERHIERARCHY_DISPLAYNAME)) {
77
-				return false;
78
-			}
79
-			$displayname = self::$decoder->getElementContent();
80
-			if (!self::$decoder->getElementEndTag()) {
81
-				return false;
82
-			}
83
-
84
-			// Type
85
-			$type = false;
86
-			if (self::$decoder->getElementStartTag(SYNC_FOLDERHIERARCHY_TYPE)) {
87
-				$type = self::$decoder->getElementContent();
88
-				if (!self::$decoder->getElementEndTag()) {
89
-					return false;
90
-				}
91
-			}
92
-		}
93
-
94
-		// endtag foldercreate, folderupdate, folderdelete
95
-		if (!self::$decoder->getElementEndTag()) {
96
-			return false;
97
-		}
98
-
99
-		$status = SYNC_FSSTATUS_SUCCESS;
100
-		// Get state of hierarchy
101
-		try {
102
-			$syncstate = self::$deviceManager->GetStateManager()->GetSyncState($synckey);
103
-			$newsynckey = self::$deviceManager->GetStateManager()->GetNewSyncKey($synckey);
104
-
105
-			// there are no SyncParameters for the hierarchy, but we use it to save the latest synckeys
106
-			$spa = self::$deviceManager->GetStateManager()->GetSynchedFolderState(false);
107
-
108
-			// Over the ChangesWrapper the HierarchyCache is notified about all changes
109
-			$changesMem = self::$deviceManager->GetHierarchyChangesWrapper();
110
-
111
-			// the hierarchyCache should now fully be initialized - check for changes in the additional folders
112
-			$changesMem->Config(GSync::GetAdditionalSyncFolders(false));
113
-
114
-			// reset to default store in backend
115
-			self::$backend->Setup(false);
116
-
117
-			// there are unprocessed changes in the hierarchy, trigger resync
118
-			if ($changesMem->GetChangeCount() > 0) {
119
-				throw new StatusException("HandleFolderChange() can not proceed as there are unprocessed hierarchy changes", SYNC_FSSTATUS_SERVERERROR);
120
-			}
121
-
122
-			// any additional folders can not be modified - with exception if they are of type SYNC_FOLDER_TYPE_UNKNOWN (ZP-907)
123
-			if (self::$deviceManager->GetFolderTypeFromCacheById($serverid) != SYNC_FOLDER_TYPE_UNKNOWN && $serverid !== false && GSync::GetAdditionalSyncFolderStore($backendid)) {
124
-				throw new StatusException("HandleFolderChange() can not change additional folders which are configured", SYNC_FSSTATUS_SYSTEMFOLDER);
125
-			}
126
-
127
-			// switch user store if this this happens inside an additional folder
128
-			// if this is an additional folder the backend has to be setup correctly
129
-			// backend should also not be switched when type is SYNC_FOLDER_TYPE_UNKNOWN (ZP-1220)
130
-			if (self::$deviceManager->GetFolderTypeFromCacheById($serverid) != SYNC_FOLDER_TYPE_UNKNOWN && !self::$backend->Setup(GSync::GetAdditionalSyncFolderStore((($parentBackendId != false) ? $parentBackendId : $backendid)))) {
131
-				throw new StatusException(sprintf("HandleFolderChange() could not Setup() the backend for folder id '%s'", (($parentBackendId != false) ? $parentBackendId : $backendid)), SYNC_FSSTATUS_SERVERERROR);
132
-			}
133
-		}
134
-		catch (StateNotFoundException $snfex) {
135
-			$status = SYNC_FSSTATUS_SYNCKEYERROR;
136
-		}
137
-		catch (StatusException $stex) {
138
-			$status = $stex->getCode();
139
-		}
140
-
141
-		// set $newsynckey in case of an error
142
-		if (!isset($newsynckey)) {
143
-			$newsynckey = $synckey;
144
-		}
145
-
146
-		if ($status == SYNC_FSSTATUS_SUCCESS) {
147
-			try {
148
-				// Configure importer with last state
149
-				$importer = self::$backend->GetImporter();
150
-				$importer->Config($syncstate);
151
-
152
-				// the messages from the PIM will be forwarded to the real importer
153
-				$changesMem->SetDestinationImporter($importer);
154
-
155
-				// Create SyncFolder object
156
-				$folder = new SyncFolder();
157
-				$folder->serverid = $serverid;
158
-				$folder->parentid = $parentBackendId;
159
-				if (isset($displayname)) {
160
-					$folder->displayname = $displayname;
161
-				}
162
-				if (isset($type)) {
163
-					$folder->type = $type;
164
-				}
165
-				// add the backendId to the SyncFolder object
166
-				$folder->BackendId = $backendid;
167
-
168
-				// process incoming change
169
-				if (!$delete) {
170
-					// when creating, $folder->serverid is false, and the returned id is already mapped by the backend
171
-					$folder = $changesMem->ImportFolderChange($folder);
172
-				}
173
-				else {
174
-					// delete folder
175
-					$changesMem->ImportFolderDeletion($folder);
176
-				}
177
-			}
178
-			catch (StatusException $stex) {
179
-				$status = $stex->getCode();
180
-			}
181
-		}
182
-
183
-		self::$encoder->startWBXML();
184
-		if ($create) {
185
-			self::$encoder->startTag(SYNC_FOLDERHIERARCHY_FOLDERCREATE);
186
-
187
-			self::$encoder->startTag(SYNC_FOLDERHIERARCHY_STATUS);
188
-			self::$encoder->content($status);
189
-			self::$encoder->endTag();
190
-
191
-			self::$encoder->startTag(SYNC_FOLDERHIERARCHY_SYNCKEY);
192
-			self::$encoder->content($newsynckey);
193
-			self::$encoder->endTag();
194
-
195
-			self::$encoder->startTag(SYNC_FOLDERHIERARCHY_SERVERENTRYID);
196
-			self::$encoder->content($folder->serverid);
197
-			self::$encoder->endTag();
198
-
199
-			self::$encoder->endTag();
200
-		}
201
-		elseif ($update) {
202
-			self::$encoder->startTag(SYNC_FOLDERHIERARCHY_FOLDERUPDATE);
203
-
204
-			self::$encoder->startTag(SYNC_FOLDERHIERARCHY_STATUS);
205
-			self::$encoder->content($status);
206
-			self::$encoder->endTag();
207
-
208
-			self::$encoder->startTag(SYNC_FOLDERHIERARCHY_SYNCKEY);
209
-			self::$encoder->content($newsynckey);
210
-			self::$encoder->endTag();
211
-
212
-			self::$encoder->endTag();
213
-		}
214
-		elseif ($delete) {
215
-			self::$encoder->startTag(SYNC_FOLDERHIERARCHY_FOLDERDELETE);
216
-
217
-			self::$encoder->startTag(SYNC_FOLDERHIERARCHY_STATUS);
218
-			self::$encoder->content($status);
219
-			self::$encoder->endTag();
220
-
221
-			self::$encoder->startTag(SYNC_FOLDERHIERARCHY_SYNCKEY);
222
-			self::$encoder->content($newsynckey);
223
-			self::$encoder->endTag();
224
-
225
-			self::$encoder->endTag();
226
-		}
227
-
228
-		self::$topCollector->AnnounceInformation(sprintf("Operation status %d", $status), true);
229
-
230
-		// Save the sync state for the next time
231
-		if (isset($importer)) {
232
-			self::$deviceManager->GetStateManager()->SetSyncState($newsynckey, $importer->GetState());
233
-
234
-			// update SPA & save it
235
-			$spa->SetSyncKey($newsynckey);
236
-			$spa->SetFolderId(false);
237
-			self::$deviceManager->GetStateManager()->SetSynchedFolderState($spa);
238
-
239
-			// invalidate all pingable flags
240
-			SyncCollections::InvalidatePingableFlags();
241
-		}
242
-
243
-		return true;
244
-	}
11
+    /**
12
+     * Handles creates, updates or deletes of a folder
13
+     * issued by the commands FolderCreate, FolderUpdate and FolderDelete.
14
+     *
15
+     * @param int $commandCode
16
+     *
17
+     * @return bool
18
+     */
19
+    public function Handle($commandCode) {
20
+        $el = self::$decoder->getElement();
21
+
22
+        if ($el[EN_TYPE] != EN_TYPE_STARTTAG) {
23
+            return false;
24
+        }
25
+
26
+        $create = $update = $delete = false;
27
+        if ($el[EN_TAG] == SYNC_FOLDERHIERARCHY_FOLDERCREATE) {
28
+            $create = true;
29
+        }
30
+        elseif ($el[EN_TAG] == SYNC_FOLDERHIERARCHY_FOLDERUPDATE) {
31
+            $update = true;
32
+        }
33
+        elseif ($el[EN_TAG] == SYNC_FOLDERHIERARCHY_FOLDERDELETE) {
34
+            $delete = true;
35
+        }
36
+
37
+        if (!$create && !$update && !$delete) {
38
+            return false;
39
+        }
40
+
41
+        // SyncKey
42
+        if (!self::$decoder->getElementStartTag(SYNC_FOLDERHIERARCHY_SYNCKEY)) {
43
+            return false;
44
+        }
45
+        $synckey = self::$decoder->getElementContent();
46
+        if (!self::$decoder->getElementEndTag()) {
47
+            return false;
48
+        }
49
+
50
+        // ServerID
51
+        $serverid = false;
52
+        $backendid = false;
53
+        if (self::$decoder->getElementStartTag(SYNC_FOLDERHIERARCHY_SERVERENTRYID)) {
54
+            $serverid = self::$decoder->getElementContent();
55
+            $backendid = self::$deviceManager->GetBackendIdForFolderId($serverid);
56
+            if (!self::$decoder->getElementEndTag()) {
57
+                return false;
58
+            }
59
+        }
60
+
61
+        // Parent
62
+        $parentid = false;
63
+        $parentBackendId = false;
64
+
65
+        // when creating or updating more information is necessary
66
+        if (!$delete) {
67
+            if (self::$decoder->getElementStartTag(SYNC_FOLDERHIERARCHY_PARENTID)) {
68
+                $parentid = self::$decoder->getElementContent();
69
+                $parentBackendId = self::$deviceManager->GetBackendIdForFolderId($parentid);
70
+                if (!self::$decoder->getElementEndTag()) {
71
+                    return false;
72
+                }
73
+            }
74
+
75
+            // Displayname
76
+            if (!self::$decoder->getElementStartTag(SYNC_FOLDERHIERARCHY_DISPLAYNAME)) {
77
+                return false;
78
+            }
79
+            $displayname = self::$decoder->getElementContent();
80
+            if (!self::$decoder->getElementEndTag()) {
81
+                return false;
82
+            }
83
+
84
+            // Type
85
+            $type = false;
86
+            if (self::$decoder->getElementStartTag(SYNC_FOLDERHIERARCHY_TYPE)) {
87
+                $type = self::$decoder->getElementContent();
88
+                if (!self::$decoder->getElementEndTag()) {
89
+                    return false;
90
+                }
91
+            }
92
+        }
93
+
94
+        // endtag foldercreate, folderupdate, folderdelete
95
+        if (!self::$decoder->getElementEndTag()) {
96
+            return false;
97
+        }
98
+
99
+        $status = SYNC_FSSTATUS_SUCCESS;
100
+        // Get state of hierarchy
101
+        try {
102
+            $syncstate = self::$deviceManager->GetStateManager()->GetSyncState($synckey);
103
+            $newsynckey = self::$deviceManager->GetStateManager()->GetNewSyncKey($synckey);
104
+
105
+            // there are no SyncParameters for the hierarchy, but we use it to save the latest synckeys
106
+            $spa = self::$deviceManager->GetStateManager()->GetSynchedFolderState(false);
107
+
108
+            // Over the ChangesWrapper the HierarchyCache is notified about all changes
109
+            $changesMem = self::$deviceManager->GetHierarchyChangesWrapper();
110
+
111
+            // the hierarchyCache should now fully be initialized - check for changes in the additional folders
112
+            $changesMem->Config(GSync::GetAdditionalSyncFolders(false));
113
+
114
+            // reset to default store in backend
115
+            self::$backend->Setup(false);
116
+
117
+            // there are unprocessed changes in the hierarchy, trigger resync
118
+            if ($changesMem->GetChangeCount() > 0) {
119
+                throw new StatusException("HandleFolderChange() can not proceed as there are unprocessed hierarchy changes", SYNC_FSSTATUS_SERVERERROR);
120
+            }
121
+
122
+            // any additional folders can not be modified - with exception if they are of type SYNC_FOLDER_TYPE_UNKNOWN (ZP-907)
123
+            if (self::$deviceManager->GetFolderTypeFromCacheById($serverid) != SYNC_FOLDER_TYPE_UNKNOWN && $serverid !== false && GSync::GetAdditionalSyncFolderStore($backendid)) {
124
+                throw new StatusException("HandleFolderChange() can not change additional folders which are configured", SYNC_FSSTATUS_SYSTEMFOLDER);
125
+            }
126
+
127
+            // switch user store if this this happens inside an additional folder
128
+            // if this is an additional folder the backend has to be setup correctly
129
+            // backend should also not be switched when type is SYNC_FOLDER_TYPE_UNKNOWN (ZP-1220)
130
+            if (self::$deviceManager->GetFolderTypeFromCacheById($serverid) != SYNC_FOLDER_TYPE_UNKNOWN && !self::$backend->Setup(GSync::GetAdditionalSyncFolderStore((($parentBackendId != false) ? $parentBackendId : $backendid)))) {
131
+                throw new StatusException(sprintf("HandleFolderChange() could not Setup() the backend for folder id '%s'", (($parentBackendId != false) ? $parentBackendId : $backendid)), SYNC_FSSTATUS_SERVERERROR);
132
+            }
133
+        }
134
+        catch (StateNotFoundException $snfex) {
135
+            $status = SYNC_FSSTATUS_SYNCKEYERROR;
136
+        }
137
+        catch (StatusException $stex) {
138
+            $status = $stex->getCode();
139
+        }
140
+
141
+        // set $newsynckey in case of an error
142
+        if (!isset($newsynckey)) {
143
+            $newsynckey = $synckey;
144
+        }
145
+
146
+        if ($status == SYNC_FSSTATUS_SUCCESS) {
147
+            try {
148
+                // Configure importer with last state
149
+                $importer = self::$backend->GetImporter();
150
+                $importer->Config($syncstate);
151
+
152
+                // the messages from the PIM will be forwarded to the real importer
153
+                $changesMem->SetDestinationImporter($importer);
154
+
155
+                // Create SyncFolder object
156
+                $folder = new SyncFolder();
157
+                $folder->serverid = $serverid;
158
+                $folder->parentid = $parentBackendId;
159
+                if (isset($displayname)) {
160
+                    $folder->displayname = $displayname;
161
+                }
162
+                if (isset($type)) {
163
+                    $folder->type = $type;
164
+                }
165
+                // add the backendId to the SyncFolder object
166
+                $folder->BackendId = $backendid;
167
+
168
+                // process incoming change
169
+                if (!$delete) {
170
+                    // when creating, $folder->serverid is false, and the returned id is already mapped by the backend
171
+                    $folder = $changesMem->ImportFolderChange($folder);
172
+                }
173
+                else {
174
+                    // delete folder
175
+                    $changesMem->ImportFolderDeletion($folder);
176
+                }
177
+            }
178
+            catch (StatusException $stex) {
179
+                $status = $stex->getCode();
180
+            }
181
+        }
182
+
183
+        self::$encoder->startWBXML();
184
+        if ($create) {
185
+            self::$encoder->startTag(SYNC_FOLDERHIERARCHY_FOLDERCREATE);
186
+
187
+            self::$encoder->startTag(SYNC_FOLDERHIERARCHY_STATUS);
188
+            self::$encoder->content($status);
189
+            self::$encoder->endTag();
190
+
191
+            self::$encoder->startTag(SYNC_FOLDERHIERARCHY_SYNCKEY);
192
+            self::$encoder->content($newsynckey);
193
+            self::$encoder->endTag();
194
+
195
+            self::$encoder->startTag(SYNC_FOLDERHIERARCHY_SERVERENTRYID);
196
+            self::$encoder->content($folder->serverid);
197
+            self::$encoder->endTag();
198
+
199
+            self::$encoder->endTag();
200
+        }
201
+        elseif ($update) {
202
+            self::$encoder->startTag(SYNC_FOLDERHIERARCHY_FOLDERUPDATE);
203
+
204
+            self::$encoder->startTag(SYNC_FOLDERHIERARCHY_STATUS);
205
+            self::$encoder->content($status);
206
+            self::$encoder->endTag();
207
+
208
+            self::$encoder->startTag(SYNC_FOLDERHIERARCHY_SYNCKEY);
209
+            self::$encoder->content($newsynckey);
210
+            self::$encoder->endTag();
211
+
212
+            self::$encoder->endTag();
213
+        }
214
+        elseif ($delete) {
215
+            self::$encoder->startTag(SYNC_FOLDERHIERARCHY_FOLDERDELETE);
216
+
217
+            self::$encoder->startTag(SYNC_FOLDERHIERARCHY_STATUS);
218
+            self::$encoder->content($status);
219
+            self::$encoder->endTag();
220
+
221
+            self::$encoder->startTag(SYNC_FOLDERHIERARCHY_SYNCKEY);
222
+            self::$encoder->content($newsynckey);
223
+            self::$encoder->endTag();
224
+
225
+            self::$encoder->endTag();
226
+        }
227
+
228
+        self::$topCollector->AnnounceInformation(sprintf("Operation status %d", $status), true);
229
+
230
+        // Save the sync state for the next time
231
+        if (isset($importer)) {
232
+            self::$deviceManager->GetStateManager()->SetSyncState($newsynckey, $importer->GetState());
233
+
234
+            // update SPA & save it
235
+            $spa->SetSyncKey($newsynckey);
236
+            $spa->SetFolderId(false);
237
+            self::$deviceManager->GetStateManager()->SetSynchedFolderState($spa);
238
+
239
+            // invalidate all pingable flags
240
+            SyncCollections::InvalidatePingableFlags();
241
+        }
242
+
243
+        return true;
244
+    }
245 245
 }
Please login to merge, or discard this patch.
Braces   +8 added lines, -16 removed lines patch added patch discarded remove patch
@@ -26,11 +26,9 @@  discard block
 block discarded – undo
26 26
 		$create = $update = $delete = false;
27 27
 		if ($el[EN_TAG] == SYNC_FOLDERHIERARCHY_FOLDERCREATE) {
28 28
 			$create = true;
29
-		}
30
-		elseif ($el[EN_TAG] == SYNC_FOLDERHIERARCHY_FOLDERUPDATE) {
29
+		} elseif ($el[EN_TAG] == SYNC_FOLDERHIERARCHY_FOLDERUPDATE) {
31 30
 			$update = true;
32
-		}
33
-		elseif ($el[EN_TAG] == SYNC_FOLDERHIERARCHY_FOLDERDELETE) {
31
+		} elseif ($el[EN_TAG] == SYNC_FOLDERHIERARCHY_FOLDERDELETE) {
34 32
 			$delete = true;
35 33
 		}
36 34
 
@@ -130,11 +128,9 @@  discard block
 block discarded – undo
130 128
 			if (self::$deviceManager->GetFolderTypeFromCacheById($serverid) != SYNC_FOLDER_TYPE_UNKNOWN && !self::$backend->Setup(GSync::GetAdditionalSyncFolderStore((($parentBackendId != false) ? $parentBackendId : $backendid)))) {
131 129
 				throw new StatusException(sprintf("HandleFolderChange() could not Setup() the backend for folder id '%s'", (($parentBackendId != false) ? $parentBackendId : $backendid)), SYNC_FSSTATUS_SERVERERROR);
132 130
 			}
133
-		}
134
-		catch (StateNotFoundException $snfex) {
131
+		} catch (StateNotFoundException $snfex) {
135 132
 			$status = SYNC_FSSTATUS_SYNCKEYERROR;
136
-		}
137
-		catch (StatusException $stex) {
133
+		} catch (StatusException $stex) {
138 134
 			$status = $stex->getCode();
139 135
 		}
140 136
 
@@ -169,13 +165,11 @@  discard block
 block discarded – undo
169 165
 				if (!$delete) {
170 166
 					// when creating, $folder->serverid is false, and the returned id is already mapped by the backend
171 167
 					$folder = $changesMem->ImportFolderChange($folder);
172
-				}
173
-				else {
168
+				} else {
174 169
 					// delete folder
175 170
 					$changesMem->ImportFolderDeletion($folder);
176 171
 				}
177
-			}
178
-			catch (StatusException $stex) {
172
+			} catch (StatusException $stex) {
179 173
 				$status = $stex->getCode();
180 174
 			}
181 175
 		}
@@ -197,8 +191,7 @@  discard block
 block discarded – undo
197 191
 			self::$encoder->endTag();
198 192
 
199 193
 			self::$encoder->endTag();
200
-		}
201
-		elseif ($update) {
194
+		} elseif ($update) {
202 195
 			self::$encoder->startTag(SYNC_FOLDERHIERARCHY_FOLDERUPDATE);
203 196
 
204 197
 			self::$encoder->startTag(SYNC_FOLDERHIERARCHY_STATUS);
@@ -210,8 +203,7 @@  discard block
 block discarded – undo
210 203
 			self::$encoder->endTag();
211 204
 
212 205
 			self::$encoder->endTag();
213
-		}
214
-		elseif ($delete) {
206
+		} elseif ($delete) {
215 207
 			self::$encoder->startTag(SYNC_FOLDERHIERARCHY_FOLDERDELETE);
216 208
 
217 209
 			self::$encoder->startTag(SYNC_FOLDERHIERARCHY_STATUS);
Please login to merge, or discard this patch.
lib/request/moveitems.php 2 patches
Indentation   +123 added lines, -123 removed lines patch added patch discarded remove patch
@@ -8,127 +8,127 @@
 block discarded – undo
8 8
  */
9 9
 
10 10
 class MoveItems extends RequestProcessor {
11
-	/**
12
-	 * Handles the MoveItems command.
13
-	 *
14
-	 * @param int $commandCode
15
-	 *
16
-	 * @return bool
17
-	 */
18
-	public function Handle($commandCode) {
19
-		if (!self::$decoder->getElementStartTag(SYNC_MOVE_MOVES)) {
20
-			return false;
21
-		}
22
-
23
-		$moves = [];
24
-		while (self::$decoder->getElementStartTag(SYNC_MOVE_MOVE)) {
25
-			$move = [];
26
-			if (self::$decoder->getElementStartTag(SYNC_MOVE_SRCMSGID)) {
27
-				$move["srcmsgid"] = self::$decoder->getElementContent();
28
-				if (!self::$decoder->getElementEndTag()) {
29
-					break;
30
-				}
31
-			}
32
-			if (self::$decoder->getElementStartTag(SYNC_MOVE_SRCFLDID)) {
33
-				$move["srcfldid"] = self::$decoder->getElementContent();
34
-				if (!self::$decoder->getElementEndTag()) {
35
-					break;
36
-				}
37
-			}
38
-			if (self::$decoder->getElementStartTag(SYNC_MOVE_DSTFLDID)) {
39
-				$move["dstfldid"] = self::$decoder->getElementContent();
40
-				if (!self::$decoder->getElementEndTag()) {
41
-					break;
42
-				}
43
-			}
44
-			array_push($moves, $move);
45
-
46
-			if (!self::$decoder->getElementEndTag()) {
47
-				return false;
48
-			}
49
-		}
50
-
51
-		if (!self::$decoder->getElementEndTag()) {
52
-			return false;
53
-		}
54
-
55
-		self::$encoder->StartWBXML();
56
-
57
-		self::$encoder->startTag(SYNC_MOVE_MOVES);
58
-
59
-		$operationResults = [];
60
-		$operationCounter = 0;
61
-		$operationTotal = count($moves);
62
-		foreach ($moves as $move) {
63
-			++$operationCounter;
64
-			self::$encoder->startTag(SYNC_MOVE_RESPONSE);
65
-			self::$encoder->startTag(SYNC_MOVE_SRCMSGID);
66
-			self::$encoder->content($move["srcmsgid"]);
67
-			self::$encoder->endTag();
68
-
69
-			$status = SYNC_MOVEITEMSSTATUS_SUCCESS;
70
-			$result = false;
71
-
72
-			try {
73
-				$sourceBackendFolderId = self::$deviceManager->GetBackendIdForFolderId($move["srcfldid"]);
74
-
75
-				// if the source folder is an additional folder the backend has to be setup correctly
76
-				if (!self::$backend->Setup(GSync::GetAdditionalSyncFolderStore($sourceBackendFolderId))) {
77
-					throw new StatusException(sprintf("HandleMoveItems() could not Setup() the backend for folder id %s/%s", $move["srcfldid"], $sourceBackendFolderId), SYNC_MOVEITEMSSTATUS_INVALIDSOURCEID);
78
-				}
79
-
80
-				$importer = self::$backend->GetImporter($sourceBackendFolderId);
81
-				if ($importer === false) {
82
-					throw new StatusException(sprintf("HandleMoveItems() could not get an importer for folder id %s/%s", $move["srcfldid"], $sourceBackendFolderId), SYNC_MOVEITEMSSTATUS_INVALIDSOURCEID);
83
-				}
84
-
85
-				// get saved SyncParameters of the source folder
86
-				$spa = self::$deviceManager->GetStateManager()->GetSynchedFolderState($move["srcfldid"]);
87
-				if (!$spa->HasSyncKey()) {
88
-					throw new StatusException(sprintf("MoveItems(): Source folder id '%s' is not fully synchronized. Unable to perform operation.", $move["srcfldid"]), SYNC_MOVEITEMSSTATUS_INVALIDSOURCEID);
89
-				}
90
-
91
-				$importer->ConfigContentParameters($spa->GetCPO());
92
-
93
-				$result = $importer->ImportMessageMove($move["srcmsgid"], self::$deviceManager->GetBackendIdForFolderId($move["dstfldid"]));
94
-				// We discard the standard importer state for now.
95
-			}
96
-			catch (StatusException $stex) {
97
-				if ($stex->getCode() == SYNC_STATUS_FOLDERHIERARCHYCHANGED) { // same as SYNC_FSSTATUS_CODEUNKNOWN
98
-					$status = SYNC_MOVEITEMSSTATUS_INVALIDSOURCEID;
99
-				}
100
-				else {
101
-					$status = $stex->getCode();
102
-				}
103
-			}
104
-
105
-			if ($operationCounter % 10 == 0) {
106
-				self::$topCollector->AnnounceInformation(sprintf("Moved %d objects out of %d", $operationCounter, $operationTotal));
107
-			}
108
-
109
-			// save the operation result
110
-			if (!isset($operationResults[$status])) {
111
-				$operationResults[$status] = 0;
112
-			}
113
-			++$operationResults[$status];
114
-
115
-			self::$encoder->startTag(SYNC_MOVE_STATUS);
116
-			self::$encoder->content($status);
117
-			self::$encoder->endTag();
118
-
119
-			self::$encoder->startTag(SYNC_MOVE_DSTMSGID);
120
-			self::$encoder->content((($result !== false) ? $result : $move["srcmsgid"]));
121
-			self::$encoder->endTag();
122
-			self::$encoder->endTag();
123
-		}
124
-
125
-		self::$topCollector->AnnounceInformation(sprintf("Moved %d - Codes", $operationTotal), true);
126
-		foreach ($operationResults as $status => $occurrences) {
127
-			self::$topCollector->AnnounceInformation(sprintf("%dx%d", $occurrences, $status), true);
128
-		}
129
-
130
-		self::$encoder->endTag();
131
-
132
-		return true;
133
-	}
11
+    /**
12
+     * Handles the MoveItems command.
13
+     *
14
+     * @param int $commandCode
15
+     *
16
+     * @return bool
17
+     */
18
+    public function Handle($commandCode) {
19
+        if (!self::$decoder->getElementStartTag(SYNC_MOVE_MOVES)) {
20
+            return false;
21
+        }
22
+
23
+        $moves = [];
24
+        while (self::$decoder->getElementStartTag(SYNC_MOVE_MOVE)) {
25
+            $move = [];
26
+            if (self::$decoder->getElementStartTag(SYNC_MOVE_SRCMSGID)) {
27
+                $move["srcmsgid"] = self::$decoder->getElementContent();
28
+                if (!self::$decoder->getElementEndTag()) {
29
+                    break;
30
+                }
31
+            }
32
+            if (self::$decoder->getElementStartTag(SYNC_MOVE_SRCFLDID)) {
33
+                $move["srcfldid"] = self::$decoder->getElementContent();
34
+                if (!self::$decoder->getElementEndTag()) {
35
+                    break;
36
+                }
37
+            }
38
+            if (self::$decoder->getElementStartTag(SYNC_MOVE_DSTFLDID)) {
39
+                $move["dstfldid"] = self::$decoder->getElementContent();
40
+                if (!self::$decoder->getElementEndTag()) {
41
+                    break;
42
+                }
43
+            }
44
+            array_push($moves, $move);
45
+
46
+            if (!self::$decoder->getElementEndTag()) {
47
+                return false;
48
+            }
49
+        }
50
+
51
+        if (!self::$decoder->getElementEndTag()) {
52
+            return false;
53
+        }
54
+
55
+        self::$encoder->StartWBXML();
56
+
57
+        self::$encoder->startTag(SYNC_MOVE_MOVES);
58
+
59
+        $operationResults = [];
60
+        $operationCounter = 0;
61
+        $operationTotal = count($moves);
62
+        foreach ($moves as $move) {
63
+            ++$operationCounter;
64
+            self::$encoder->startTag(SYNC_MOVE_RESPONSE);
65
+            self::$encoder->startTag(SYNC_MOVE_SRCMSGID);
66
+            self::$encoder->content($move["srcmsgid"]);
67
+            self::$encoder->endTag();
68
+
69
+            $status = SYNC_MOVEITEMSSTATUS_SUCCESS;
70
+            $result = false;
71
+
72
+            try {
73
+                $sourceBackendFolderId = self::$deviceManager->GetBackendIdForFolderId($move["srcfldid"]);
74
+
75
+                // if the source folder is an additional folder the backend has to be setup correctly
76
+                if (!self::$backend->Setup(GSync::GetAdditionalSyncFolderStore($sourceBackendFolderId))) {
77
+                    throw new StatusException(sprintf("HandleMoveItems() could not Setup() the backend for folder id %s/%s", $move["srcfldid"], $sourceBackendFolderId), SYNC_MOVEITEMSSTATUS_INVALIDSOURCEID);
78
+                }
79
+
80
+                $importer = self::$backend->GetImporter($sourceBackendFolderId);
81
+                if ($importer === false) {
82
+                    throw new StatusException(sprintf("HandleMoveItems() could not get an importer for folder id %s/%s", $move["srcfldid"], $sourceBackendFolderId), SYNC_MOVEITEMSSTATUS_INVALIDSOURCEID);
83
+                }
84
+
85
+                // get saved SyncParameters of the source folder
86
+                $spa = self::$deviceManager->GetStateManager()->GetSynchedFolderState($move["srcfldid"]);
87
+                if (!$spa->HasSyncKey()) {
88
+                    throw new StatusException(sprintf("MoveItems(): Source folder id '%s' is not fully synchronized. Unable to perform operation.", $move["srcfldid"]), SYNC_MOVEITEMSSTATUS_INVALIDSOURCEID);
89
+                }
90
+
91
+                $importer->ConfigContentParameters($spa->GetCPO());
92
+
93
+                $result = $importer->ImportMessageMove($move["srcmsgid"], self::$deviceManager->GetBackendIdForFolderId($move["dstfldid"]));
94
+                // We discard the standard importer state for now.
95
+            }
96
+            catch (StatusException $stex) {
97
+                if ($stex->getCode() == SYNC_STATUS_FOLDERHIERARCHYCHANGED) { // same as SYNC_FSSTATUS_CODEUNKNOWN
98
+                    $status = SYNC_MOVEITEMSSTATUS_INVALIDSOURCEID;
99
+                }
100
+                else {
101
+                    $status = $stex->getCode();
102
+                }
103
+            }
104
+
105
+            if ($operationCounter % 10 == 0) {
106
+                self::$topCollector->AnnounceInformation(sprintf("Moved %d objects out of %d", $operationCounter, $operationTotal));
107
+            }
108
+
109
+            // save the operation result
110
+            if (!isset($operationResults[$status])) {
111
+                $operationResults[$status] = 0;
112
+            }
113
+            ++$operationResults[$status];
114
+
115
+            self::$encoder->startTag(SYNC_MOVE_STATUS);
116
+            self::$encoder->content($status);
117
+            self::$encoder->endTag();
118
+
119
+            self::$encoder->startTag(SYNC_MOVE_DSTMSGID);
120
+            self::$encoder->content((($result !== false) ? $result : $move["srcmsgid"]));
121
+            self::$encoder->endTag();
122
+            self::$encoder->endTag();
123
+        }
124
+
125
+        self::$topCollector->AnnounceInformation(sprintf("Moved %d - Codes", $operationTotal), true);
126
+        foreach ($operationResults as $status => $occurrences) {
127
+            self::$topCollector->AnnounceInformation(sprintf("%dx%d", $occurrences, $status), true);
128
+        }
129
+
130
+        self::$encoder->endTag();
131
+
132
+        return true;
133
+    }
134 134
 }
Please login to merge, or discard this patch.
Braces   +2 added lines, -4 removed lines patch added patch discarded remove patch
@@ -92,12 +92,10 @@
 block discarded – undo
92 92
 
93 93
 				$result = $importer->ImportMessageMove($move["srcmsgid"], self::$deviceManager->GetBackendIdForFolderId($move["dstfldid"]));
94 94
 				// We discard the standard importer state for now.
95
-			}
96
-			catch (StatusException $stex) {
95
+			} catch (StatusException $stex) {
97 96
 				if ($stex->getCode() == SYNC_STATUS_FOLDERHIERARCHYCHANGED) { // same as SYNC_FSSTATUS_CODEUNKNOWN
98 97
 					$status = SYNC_MOVEITEMSSTATUS_INVALIDSOURCEID;
99
-				}
100
-				else {
98
+				} else {
101 99
 					$status = $stex->getCode();
102 100
 				}
103 101
 			}
Please login to merge, or discard this patch.