Test Failed
Push — master ( 647c72...cd42b5 )
by
unknown
10:25
created

server/includes/modules/class.delegatesmodule.php (1 issue)

Severity
1
<?php
2
	/**
3
	 * DelegatesModule
4
	 * Class can be used to get delegate information of a particular user.
5
	 * The delegate information can be created/update using this class as well.
6
	 */
7
	class DelegatesModule extends Module
8
	{
9
		/**
10
		 * @var array contains entryid's of all default folders.
11
		 */
12
		private $defaultFolders;
13
14
		/**
15
		 * @var array contains delegate properties from special message (LocalFreebusy).
16
		 */
17
		private $delegateProps;
18
19
		/**
20
		 * @var Resource of LocalFreeBusy Message. This contains $delegateProps for delegates.
21
		 */
22
		private $localFreeBusyMessage;
23
24
		/**
25
		 * @var Resource of FreeBusy Folder in IPM_SUBTREE. This permissions for freebusy folder used in calendar.
26
		 */
27
		private $freeBusyFolder;
28
29
		/**
30
		 * @var Resource of default store of the current user.
31
		 */
32
		private $defaultStore;
33
34
		/**
35
		 * Constructor
36
		 * @param int $id unique id.
37
		 * @param array $data list of all actions.
38
		 */
39
		function __construct($id, $data)
40
		{
41
			$this->defaultFolders = array();
42
			$this->delegateProps = array();
43
			$this->localFreeBusyMessage = false;
44
			$this->freeBusyFolder = false;
45
			$this->defaultStore = false;
46
47
			parent::__construct($id, $data);
48
		}
49
50
		/**
51
		 * Executes all the actions in the $data variable
52
		 */
53
		function execute()
54
		{
55
			foreach($this->data as $actionType => $action)
56
			{
57
				if(isset($actionType)) {
58
					try {
59
						switch($actionType)
60
						{
61
							case 'list':
62
								$this->delegateList();
63
								break;
64
							case 'open':
65
								$this->openDelegate($action);
66
								break;
67
							case 'save':
68
								$this->saveDelegates($action);
69
								break;
70
							case 'delete':
71
								$this->deleteDelegates($action);
72
								break;
73
							default:
74
								$this->handleUnknownActionType($actionType);
75
						}
76
					} catch (MAPIException $e) {
77
						$this->processException($e, $actionType);
78
					}
79
				}
80
			}
81
		}
82
83
		/******** Generic functions to access data ***********/
84
85
		/**
86
		 * Function will return values of the properties PR_DELEGATES_SEE_PRIVATE, PR_SCHDINFO_DELEGATE_ENTRYIDS and
87
		 * PR_SCHDINFO_DELEGATE_NAMES from LocalFreeBusyMessage of the user's store.
88
		 * @param {MAPIMessage} $localFreeBusyMessage (optional) local freebusy message of the user's store.
89
		 * @return {Array} values of delegate properties.
90
		 */
91
		function getDelegateProps($localFreeBusyMessage = false)
92
		{
93
			if(empty($this->delegateProps)) {
94
				if($localFreeBusyMessage === false) {
95
					$localFreeBusyMessage = freebusy::getLocalFreeBusyMessage();
96
				}
97
98
				$this->delegateProps = mapi_getprops($localFreeBusyMessage, array(PR_DELEGATES_SEE_PRIVATE, PR_SCHDINFO_DELEGATE_ENTRYIDS, PR_SCHDINFO_DELEGATE_NAMES));
99
100
				// check if properties exists or not, if not then initialize with default values
101
				// this way in caller functions we don't need to check for non-existent properties
102
				if(!isset($this->delegateProps[PR_DELEGATES_SEE_PRIVATE])) {
103
					$this->delegateProps[PR_DELEGATES_SEE_PRIVATE] = array();
104
				}
105
106
				if(!isset($this->delegateProps[PR_SCHDINFO_DELEGATE_ENTRYIDS])) {
107
					$this->delegateProps[PR_SCHDINFO_DELEGATE_ENTRYIDS] = array();
108
				}
109
110
				if(!isset($this->delegateProps[PR_SCHDINFO_DELEGATE_NAMES])) {
111
					$this->delegateProps[PR_SCHDINFO_DELEGATE_NAMES] = array();
112
				}
113
			}
114
115
			return $this->delegateProps;
116
		}
117
118
		/**
119
		 * Function will return array of entryids of default folders of the user's store.
120
		 * @param {MAPIStore} $store (optional) user's store.
121
		 * @return {Array} default folder entryids.
122
		 */
123
		function getDefaultFolders($store = false)
124
		{
125
			if(empty($this->defaultFolders)) {
126
				if($store === false) {
127
					$store = $this->getDefaultStore();
128
				}
129
130
				// Get root store
131
				$root = mapi_msgstore_openentry($store, null);
132
133
				// Get Inbox folder
134
				$inbox = mapi_msgstore_getreceivefolder($store);
135
				$inboxprops = mapi_getprops($inbox, Array(PR_ENTRYID));
136
137
				// Get entryids of default folders.
138
				$rootStoreProps = mapi_getprops($root, array(PR_IPM_APPOINTMENT_ENTRYID, PR_IPM_TASK_ENTRYID, PR_IPM_CONTACT_ENTRYID, PR_IPM_NOTE_ENTRYID, PR_IPM_JOURNAL_ENTRYID));
139
				
140
				$this->defaultFolders = array(
141
					'calendar' 		=> $rootStoreProps[PR_IPM_APPOINTMENT_ENTRYID],
142
					'tasks' 		=> $rootStoreProps[PR_IPM_TASK_ENTRYID],
143
					'inbox' 		=> $inboxprops[PR_ENTRYID],
144
					'contacts'		=> $rootStoreProps[PR_IPM_CONTACT_ENTRYID],
145
					'notes'			=> $rootStoreProps[PR_IPM_NOTE_ENTRYID],
146
					'journal'		=> $rootStoreProps[PR_IPM_JOURNAL_ENTRYID]
147
				);
148
			}
149
150
			return $this->defaultFolders;
151
		}
152
153
		/**
154
		 * Function will return index of a particular delegate, this index can be used to get information of
155
		 * delegate from PR_DELEGATES_SEE_PRIVATE, PR_SCHDINFO_DELEGATE_ENTRYIDS and
156
		 * PR_SCHDINFO_DELEGATE_NAMES properties.
157
		 * @param {BinEntryid} $entryId entryid of delegate.
158
		 * @return {Number} index of the delegate information.
159
		 */
160
		function getDelegateIndex($entryId)
161
		{
162
			$delegateProps = $this->getDelegateProps();
163
164
			// Check if user is existing delegate.
165
			if(!empty($delegateProps[PR_SCHDINFO_DELEGATE_ENTRYIDS])) {
166
				return array_search($entryId, $delegateProps[PR_SCHDINFO_DELEGATE_ENTRYIDS]);
167
			} else {
168
				return false;
169
			}
170
		}
171
172
		/**
173
		 * Function will return resource of the default store of the current logged in user.
174
		 * @return {MAPIStore} current user's store.
175
		 */
176
		function getDefaultStore()
177
		{
178
			if(!$this->defaultStore) {
179
				$this->defaultStore = $GLOBALS['mapisession']->getDefaultMessageStore();
180
			}
181
182
			return $this->defaultStore;
183
		}
184
185
		/**
186
		 * Function will return properties of the user from addressbook based on passed user's entryid.
187
		 * @param {BinEntryid} $userEntryId entryid of the user from addressbook.
188
		 * @return {Array} properties of user from addressbook.
189
		 */
190
		function getUserInfo($userEntryId)
191
		{
192
			// default return stuff
193
			$result = array(
194
				'display_name' => _('Unknown user/group'),
195
				'entryid' => null
196
			);
197
198
			// open the addressbook
199
			$ab = $GLOBALS['mapisession']->getAddressbook();
200
201
			try {
202
				// try userid as normal user
203
				$user = mapi_ab_openentry($ab, $userEntryId);
204
			} catch (MAPIException $e) {
205
				if($e->getCode() === MAPI_E_NOT_FOUND) {
206
					$e->setHandled();
207
					return $result;
208
				}
209
			}
210
211
			$props = mapi_getprops($user, array(PR_DISPLAY_NAME));
212
			$result['display_name'] = $props[PR_DISPLAY_NAME];
213
			$result['entryid'] = bin2hex($userEntryId);
214
215
			return $result; 
216
		}
217
218
		/******** Functions to get delegates information ***********/
219
220
		/**
221
		 * Function will return all the delegates information for current user.
222
		 */
223
		function delegateList()
224
		{
225
			$delegateProps = $this->getDelegateProps();
226
227
			$data = array();
228
229
			// get delegate meeting rule
230
			$delegateMeetingRule = $this->getDelegateMeetingRule();
231
232
			// Get permissions of all delegates.
233
			if(!empty($delegateProps[PR_SCHDINFO_DELEGATE_ENTRYIDS])) {
234
				for($i = 0, $len = count($delegateProps[PR_SCHDINFO_DELEGATE_ENTRYIDS]); $i < $len; $i++) {
235
					array_push($data, $this->getDelegatePermissions($delegateProps[PR_SCHDINFO_DELEGATE_ENTRYIDS][$i], $delegateMeetingRule));
236
				}
237
			}
238
239
			$this->addActionData('list', array('item' => $data));
240
			$GLOBALS['bus']->addData($this->getResponseData());
241
		}
242
243
		/**
244
		 * Function will return the permissions assigned for a particular delegate user.
245
		 * @param {Array} $delegate the delegate information sent by client.
246
		 */
247
		function openDelegate($delegate)
248
		{
249
			// Get permissions of a delegate.
250
			$data = $this->getDelegatePermissions(hex2bin($delegate['entryid']));
251
252
			$this->addActionData('item', array('item' => $data));
253
			$GLOBALS['bus']->addData($this->getResponseData());
254
		}
255
256
		/**
257
		 * Function will return information of a particular delegate from current user's store.
258
		 * @param {BinEntryid} $userEntryId entryid of the delegate.
259
		 * @param {Array} $delegateMeetingRule (optional) information of the delegate meeting rule that can be used to check if
260
		 * current delegate exists in the meeting rule.
261
		 * @return {Array} delegate information.
262
		 */
263
		function getDelegatePermissions($userEntryId, $delegateMeetingRule = false)
264
		{
265
			$delegateProps = $this->getDelegateProps();
266
			$delegateIndex = $this->getDelegateIndex($userEntryId);
267
			$userinfo = $this->getUserInfo($userEntryId);
268
269
			$delegate = array();
270
			$delegate['entryid'] = bin2hex($userEntryId);
271
272
			$delegate['props'] = array();
273
			$delegate['props']['display_name'] = $userinfo['display_name'];
274
			$delegate['props']['can_see_private'] = isset($delegateProps[PR_DELEGATES_SEE_PRIVATE][$delegateIndex]) ? ($delegateProps[PR_DELEGATES_SEE_PRIVATE][$delegateIndex] == 1) : false;
275
276
			$delegate['props'] = array_merge($delegate['props'], $this->getFolderPermissions($userEntryId));
277
278
			return $delegate;
279
		}
280
281
		/**
282
		 * Function will return folder permissions of a delegate user.
283
		 * @param {BinEntryid} $userEntryId entryid of the delegate.
284
		 * @return {Array} folder permissions of a delegate user.
285
		 */
286
		function getFolderPermissions($userEntryId)
287
		{
288
			$delegateRights = array();
289
			$store = $this->getDefaultStore();
290
291
			foreach($this->getDefaultFolders($store) as $folderName => $folderEntryId) {
292
				$folder = mapi_msgstore_openentry($store, $folderEntryId);
293
294
				// Get all users who has permissions
295
				$grants = mapi_zarafa_getpermissionrules($folder, ACCESS_TYPE_GRANT);
296
297
				// Find current delegate and get permission.
298
				foreach($grants as $id => $grant) {
299
					if($GLOBALS["entryid"]->compareABEntryIds(bin2hex($userEntryId), bin2hex($grant['userid']))) {
300
						$delegateRights['rights_' . $folderName] = $grant['rights'];
301
					}
302
				}
303
			}
304
305
			return $delegateRights;
306
		}
307
308
		/**
309
		 * Function will return properties of meeting rule that is used to send meeting related messages to delegate.
310
		 * @return {Array} delegate meeting rule information.
311
		 */
312
		function getDelegateMeetingRule()
313
		{
314
			$inbox = mapi_msgstore_getreceivefolder($this->getDefaultStore());
315
			$rulesTable = mapi_folder_getrulestable($inbox);
316
			// get delegate meeting rule
317
			$restriction = Array(RES_CONTENT,
318
						Array(
319
							FUZZYLEVEL => FL_FULLSTRING | FL_IGNORECASE,
320
							ULPROPTAG => PR_RULE_PROVIDER,
321
							VALUE => Array(
322
								PR_RULE_PROVIDER => 'Schedule+ EMS Interface'
323
							)
324
						)
325
			);
326
			mapi_table_restrict($rulesTable, $restriction);
327
			// there will be only one rule, so fetch that only
328
			$delegateMeetingRule = mapi_table_queryrows($rulesTable, $GLOBALS['properties']->getRulesProperties(), 0, 1);
329
			return !empty($delegateMeetingRule) ? $delegateMeetingRule[0] : false;
330
		}
331
332
		/******** Functions to update delegates information ***********/
333
334
		/**
335
		 * Function which saves delegates information sent from client.
336
		 * @param {Array} $delegates the delegates information sent by client.
337
		 */
338
		function saveDelegates($delegates)
339
		{
340
			$responseData = array();
341
342
			// @FIXME currently client only sends a single delegate in a request, if we can change that to contain
343
			// multiple delegates that would be good
344
345
			if(is_assoc_array($delegates)) {
346
				// wrap single delegate in an array
347
				$delegates = array($delegates);
348
			}
349
350
			for($index = 0, $len = count($delegates); $index < $len; $index++) {
351
				$delegate = $delegates[$index];
352
				$this->setFolderPermissions($delegate);
353
				// set properties for delegates on user's freebusy folder
354
				array_push($responseData, array('entryid' => $delegate['entryid']));
355
			}
356
			$this->setDelegateProps($delegates);
357
			// set delegate meeting rule
358
			$this->setDelegateMeetingRule($delegates);
359
360
			// send response to indicate success
361
			if(!empty($responseData)) {
362
				$this->addActionData('update', array('item' => $responseData));
363
				$GLOBALS['bus']->addData($this->getResponseData());
364
			}
365
		}
366
367
		/**
368
		 * Function will update PR_DELEGATES_SEE_PRIVATE, PR_SCHDINFO_DELEGATE_ENTRYIDS and
369
		 * PR_SCHDINFO_DELEGATE_NAMES properties in the current user's store.
370
		 */
371
		function setDelegateProps($delegates)
372
		{
373
			$localFreeBusyMessage = freebusy::getLocalFreeBusyMessage();
374
			$delegateProps = $this->getDelegateProps($localFreeBusyMessage);
375
			$len = count($delegates);
376
			for ($i=0; $i<$len; $i++) {
377
				$delegate = $delegates[$i];
378
				$len1 = count($delegateProps[PR_SCHDINFO_DELEGATE_ENTRYIDS]);
379
				for ($j=0; $j<$len1; $j++) {
380
					if ($delegateProps[PR_SCHDINFO_DELEGATE_ENTRYIDS][$j] == hex2bin($delegate['entryid'])) {
381
						break;
382
					}
383
				}
384
				$delegateProps[PR_SCHDINFO_DELEGATE_ENTRYIDS][$j] = hex2bin($delegate['entryid']);
385
				if (isset($delegate['props']['display_name'])) {
386
					$delegateProps[PR_SCHDINFO_DELEGATE_NAMES][$j] = $delegate['props']['display_name'];
387
				} else {
388
					$addrBook = $GLOBALS['mapisession']->getAddressbook();
389
					$user = mapi_ab_openentry($addrBook, hex2bin($delegate['entryid']));
390
					if (empty($user)) {
391
						$delegateProps[PR_SCHDINFO_DELEGATE_NAMES][$j] = "";
392
					} else {
393
						$userProps = mapi_getprops($user, array(PR_SMTP_ADDRESS));
394
						if (empty($userProps[PR_SMTP_ADDRESS])) {
395
							$delegateProps[PR_SCHDINFO_DELEGATE_NAMES][$j] = "";
396
						} else {
397
							$delegateProps[PR_SCHDINFO_DELEGATE_NAMES][$j] = $userProps[PR_SMTP_ADDRESS];
398
						}
399
					}
400
				}
401
				if (isset($delegate['props']['can_see_private'])) {
402
					$delegateProps[PR_DELEGATES_SEE_PRIVATE][$j] = $delegate['props']['can_see_private'];
403
				} else {
404
					$delegateProps[PR_DELEGATES_SEE_PRIVATE][$j] = false;
405
				}
406
			}
407
			mapi_setprops($localFreeBusyMessage, $delegateProps);
408
			mapi_savechanges($localFreeBusyMessage);
409
			// unset the module variable, so subsequent calls will have the updated value
410
			unset($this->delegateProps);
411
		}
412
413
		/**
414
		 * Function will set folder permissions for a delegate user.
415
		 * @param {Array} $delegate delegate information sent from client.
416
		 */
417
		function setFolderPermissions($delegate)
418
		{
419
			$store = $this->getDefaultStore();
420
421
			// Get all default folders and set permissions.
422
			foreach($this->getDefaultFolders($store) as $folderName => $folderEntryID) {
423
				// we need to only modify those permissions which are modified on client
424
				if(isset($delegate['props']['rights_' . $folderName]) && $delegate['props']['rights_' . $folderName] !== '') {
425
					$folder = mapi_msgstore_openentry($store, $folderEntryID);
426
427
					// Set new permissions.
428
					$acls = array(
429
							array(
430
								'type' => ACCESS_TYPE_GRANT,
431
								'userid' => hex2bin($delegate['entryid']),
432
								'rights' => $delegate['props']['rights_' . $folderName],
433
								'state' => RIGHT_NEW | RIGHT_AUTOUPDATE_DENIED
434
							)
435
					);
436
437
					mapi_zarafa_setpermissionrules($folder, $acls);
438
					mapi_savechanges($folder);
439
440
					if ($folderName === 'calendar') {
441
						$freeBusyFolder = freebusy::getLocalFreeBusyFolder($store);
442
443
						if(isset($freeBusyFolder)) {
444
							// set permissions on free/busy message
445
							$acls[0]['rights'] |= ecRightsDefaultPublic;
446
447
							mapi_zarafa_setpermissionrules($freeBusyFolder, $acls);
448
							mapi_savechanges($freeBusyFolder);
449
						}
450
					}
451
				}
452
			}
453
		}
454
455
		/** 
456
		 * Function which creates/modifies delegate meeting rule in user store
457
		 * to send meeting request mails to delegates also.
458
		 * @param {Array} $delegates all delegate information
459
		 */
460
		function setDelegateMeetingRule($delegates)
461
		{
462
			$delegateMeetingRule = $this->getDelegateMeetingRule();
463
			if (isset($delegateMeetingRule)) {
464
				$users = $delegateMeetingRule[PR_RULE_ACTIONS][0]['adrlist'];
465
			} else {
466
				$users = array();
467
			}
468
			// open addressbook to get information of all users
469
			$addrBook = $GLOBALS['mapisession']->getAddressbook();
470
			$len = count($delegates);
471
			for ($i=0; $i<$len; $i++) {
472
				$delegate = $delegates[$i];
473
				// get user info, using entryid
474
				$user = mapi_ab_openentry($addrBook, hex2bin($delegate['entryid']));
475
				$userProps = mapi_getprops($user, Array(PR_ENTRYID, PR_ADDRTYPE, PR_EMAIL_ADDRESS, PR_DISPLAY_NAME, PR_SEARCH_KEY, PR_SMTP_ADDRESS, PR_OBJECT_TYPE, PR_DISPLAY_TYPE, PR_DISPLAY_TYPE_EX));
476
477
				if (is_array($userProps)) {
478
					// add recipient type prop, to specify type of recipient in mail
479
					$userProps[PR_RECIPIENT_TYPE] = MAPI_TO;
480
					$len1 = count($users);
481
					for ($j=0; $j<$len1; $j++) {
482
						if ($userProps[PR_ENTRYID] == $users[$j][PR_ENTRYID]) {
483
							break;
484
						}
485
					}
486
					$users[$j] = $userProps;
487
				}
488
			}
489
			// only continue if any delegate has set the flag
490
			if (!empty($users)) {
491
				if ($delegateMeetingRule === false) {
492
					$this->createDelegateMeetingRule($users);
493
				} else {
494
					$this->modifyDelegateMeetingRule($delegateMeetingRule, $users);
495
				}
496
			}
497
		}
498
499
		/**
500
		 * Function will create a new delegate meeting rule if it is not present in current user's store.
501
		 * @param {Array} $usersInfo user properties which should be added in PR_RULE_ACTIONS.
502
		 */
503
		function createDelegateMeetingRule($usersInfo)
504
		{
505
			// create new rule
506
			$rule = Array();
507
508
			// no need to pass rule_id when creating new rule
509
			$rule[PR_RULE_ACTIONS] = Array(
510
							Array(
511
								'action' => OP_DELEGATE,
512
								// don't set this value it will have no effect, its hardcoded to FWD_PRESERVE_SENDER | FWD_DO_NOT_MUNGE_MSG
513
								'flavor' => 0,
514
								'flags' => 0,
515
								'adrlist' => $usersInfo
516
							)
517
			);
518
519
			$rule[PR_RULE_CONDITION] = Array(RES_AND,
520
								Array(
521
									Array(RES_CONTENT,
522
										Array(
523
											FUZZYLEVEL => FL_PREFIX,
524
											ULPROPTAG => PR_MESSAGE_CLASS,
525
											VALUE => Array(PR_MESSAGE_CLASS => 'IPM.Schedule.Meeting')
526
										)
527
									),
528
									Array(RES_NOT,
529
										Array(
530
											Array(RES_EXIST,
531
												Array(
532
													ULPROPTAG => PR_DELEGATED_BY_RULE
533
												)
534
											)
535
										)
536
									),
537
									Array(RES_OR,
538
										Array(
539
											Array(RES_NOT,
540
												Array(
541
													Array(RES_EXIST,
542
														Array(
543
															ULPROPTAG => PR_SENSITIVITY
544
														)
545
													)
546
												)
547
											),
548
											Array(RES_PROPERTY,
549
												Array(
550
													RELOP => RELOP_NE,
551
													ULPROPTAG => PR_SENSITIVITY,
552
													VALUE => Array(PR_SENSITIVITY => SENSITIVITY_PRIVATE)
553
												)
554
											)
555
										)
556
									),
557
								)
558
			);
559
560
			$rule[PR_RULE_NAME] = '';
561
			$rule[PR_RULE_PROVIDER_DATA] = '';		// 0 byte binary string
562
			$rule[PR_RULE_STATE] = ST_ENABLED;
563
			$rule[PR_RULE_LEVEL] = 0;
564
			$rule[PR_RULE_SEQUENCE] = 0;
565
			$rule[PR_RULE_PROVIDER] = 'Schedule+ EMS Interface';
566
			$rule[PR_RULE_USER_FLAGS] = 0;
567
568
			$rows = Array(
569
					0 => Array(
570
						'rowflags' => ROW_ADD,
571
						'properties' => $rule
572
					)
573
			);
574
			$inbox = mapi_msgstore_getreceivefolder($this->getDefaultStore());
575
			mapi_folder_modifyrules($inbox, $rows);
576
		}
577
578
		function modifyDelegateMeetingRule($delegateMeetingRule, $users)
579
		{
580
			$inbox = mapi_msgstore_getreceivefolder($this->getDefaultStore());
581
			if(count($users) > 0) {
582
				// update the adrlist in the rule
583
				$delegateMeetingRule[PR_RULE_ACTIONS][0]['adrlist'] = $users;
584
585
				$rows = Array(
586
						Array(
587
							'rowflags' => ROW_MODIFY,
588
							'properties' => $delegateMeetingRule
589
						)
590
				);
591
				
592
			} else {
593
				// no users remaining in the rule so delete the rule
594
				$rows = Array(
595
						0 => Array(
596
							'rowflags' => ROW_REMOVE,
597
							'properties' => $delegateMeetingRule
598
						)
599
				);
600
			}
601
			mapi_folder_modifyrules($inbox, $rows);
602
		}
603
604
		/******** Functions to delete delegates information ***********/
605
606
		/**
607
		 * Function which deletes delegates information sent by client.
608
		 * @param {Array} $delegates delegates information sent by client
609
		 */
610
		function deleteDelegates($delegates)
611
		{
612
			if (is_assoc_array($delegates)) {
613
				// wrap single delegate in an array
614
				$delegates = array($delegates);
615
			}
616
			foreach ($delegates as $delegate) {
617
				// set properties for delegates on user's freebusy folder
618
				$this->deleteDelegateProps($delegate);
619
620
				// set permissions on user's default folders
621
				$this->deleteFolderPermissions($delegate);
622
			}
623
			// delete delegate meeting rule
624
			$this->removeDelegatesFromDelegateMeetingRule($delegates);
625
			$this->sendFeedback(true);
626
		}
627
628
		/**
629
		 * Function will delete values from PR_DELEGATES_SEE_PRIVATE, PR_SCHDINFO_DELEGATE_ENTRYIDS and PR_SCHDINFO_DELEGATE_NAMES and save the properties back if its not empty.
630
		 * @param {Array} $delegate delegate information sent from client.
631
		 */
632
		function deleteDelegateProps($delegate)
633
		{
634
			$localFreeBusyMessage = freebusy::getLocalFreeBusyMessage();
635
			$delegateProps = $this->getDelegateProps($localFreeBusyMessage);
636
			$delegateIndex = -1;
637
			$len = count($delegateProps[PR_SCHDINFO_DELEGATE_ENTRYIDS]);
638
			for ($i=0; $i<$len; $i++) {
639
				if ($delegateProps[PR_SCHDINFO_DELEGATE_ENTRYIDS][$i] == hex2bin($delegate["entryid"])) {
640
					$delegateIndex = $i;
641
					break;	
642
				}
643
			}
644
			if (-1 == $delegateIndex) {
645
				return;
646
			}
647
			unset($delegateProps[PR_DELEGATES_SEE_PRIVATE][$delegateIndex]);
648
			unset($delegateProps[PR_SCHDINFO_DELEGATE_ENTRYIDS][$delegateIndex]);
649
			unset($delegateProps[PR_SCHDINFO_DELEGATE_NAMES][$delegateIndex]);
650
651
			// unset will remove the value but will not regenerate array keys, so we need to
652
			// do it here
653
			$delegateProps[PR_DELEGATES_SEE_PRIVATE] = array_values($delegateProps[PR_DELEGATES_SEE_PRIVATE]);
654
			$delegateProps[PR_SCHDINFO_DELEGATE_ENTRYIDS] = array_values($delegateProps[PR_SCHDINFO_DELEGATE_ENTRYIDS]);
655
			$delegateProps[PR_SCHDINFO_DELEGATE_NAMES] = array_values($delegateProps[PR_SCHDINFO_DELEGATE_NAMES]);
656
657
			if(!empty($delegateProps[PR_SCHDINFO_DELEGATE_ENTRYIDS])) {
658
				mapi_setprops($localFreeBusyMessage, $delegateProps);
659
			} else {
660
				// Delete delegate properties.
661
				mapi_deleteprops($localFreeBusyMessage, array(PR_DELEGATES_SEE_PRIVATE, PR_SCHDINFO_DELEGATE_ENTRYIDS, PR_SCHDINFO_DELEGATE_NAMES));
662
			}
663
664
			mapi_savechanges($localFreeBusyMessage);
665
666
			// unset the module variable, so subsequent calls will have the updated value
667
			unset($this->delegateProps);
668
		}
669
670
		/**
671
		 * Function which deletes permissions from all default folder for a particular delegate.
672
		 * @param {Array} $delegate delegate's information sent by client.
673
		 */
674
		function deleteFolderPermissions($delegate)
675
		{
676
			$store = $this->getDefaultStore();
677
678
			// Get all default folders and set permissions.
679
			foreach($this->getDefaultFolders($store) as $folderName => $folderEntryID) {
680
				$folder = mapi_msgstore_openentry($store, $folderEntryID);
681
682
				// delete current acl's
683
				$acls = array(
684
						array(
685
							'type' => ACCESS_TYPE_GRANT,
686
							'userid' => hex2bin($delegate['entryid']),
687
							'rights' => ecRightsNone,
688
							'state' => RIGHT_DELETED | RIGHT_AUTOUPDATE_DENIED
689
						)
690
				);
691
692
				mapi_zarafa_setpermissionrules($folder, $acls);
693
694
				if ($folderName === 'calendar') {
695
					$freeBusyFolder = freebusy::getLocalFreeBusyFolder($store);
696
697
					if(isset($freeBusyFolder)) {
698
						mapi_zarafa_setpermissionrules($freeBusyFolder, $acls);
699
						mapi_savechanges($freeBusyFolder);
700
					}
701
				}
702
703
				mapi_savechanges($folder);
704
			}
705
		}
706
707
		/**
708
		 * Function will remove delegates from delegate meeting rule when the user is deleted from delegate list.
709
		* @param {Array} $delegates all delegate information that are deleted
710
		 */
711
		function removeDelegatesFromDelegateMeetingRule($delegates)
712
		{
713
			$delegateMeetingRule = $this->getDelegateMeetingRule();
714
			if ($delegateMeetingRule === false) {
715
				// no delegate rule exists, nothing to do
716
				return;
717
			}
718
			$len = count($delegates);
719
			$old_users = $delegateMeetingRule[PR_RULE_ACTIONS][0]['adrlist'];
720
			$new_users = array();
721
			foreach ($old_users as $user) {
722
				for($index=0; $index<$len; $index++) {
723
					if ($user[PR_ENTRYID] == hex2bin($delegates[$index]['entryid'])) {
724
						break;
725
					}
726
				}
727
				if ($index == $len) {
728
					$new_users[] = $user;
729
				}
730
			}
731
			$this->modifyDelegateMeetingRule($delegateMeetingRule, $new_users);
732
		}
733
734
		/******** Functions for exception handling ***********/
735
736
		/**
737
		 * Function does customization of MAPIException based on module data.
738
		 * like, here it will generate display message based on actionType
739
		 * for particular exception.
740
		 * 
741
		 * @param object $e Exception object
742
		 * @param string $actionType the action type, sent by the client
743
		 * @param MAPIobject $store Store object of the current user.
744
		 * @param string $parententryid parent entryid of the message.
745
		 * @param string $entryid entryid of the message/folder.
746
		 * @param array $action the action data, sent by the client
747
		 */
748
		function handleException(&$e, $actionType = null, $store = null, $parententryid = null, $entryid = null, $action = null)
749
		{
750
			switch($actionType) {
751
				case 'save':
752
					$e->setDisplayMessage(_('Could not save delegate information.'));
753
					break;
754
				case 'delete':
755
					$e->setDisplayMessage(_('Could not delete delegate.'));
756
					break;
757
				case 'list':
758
					$e->setDisplayMessage(_('Can not get list of delegates.'));
759
					break;
760
			}
761
762
			parent::handleException($e, $actionType, $store, $parententryid, $entryid, $action);
763
		}
764
	}
765
?>
0 ignored issues
show
It is not recommended to use PHP's closing tag ?> in files other than templates.

Using a closing tag in PHP files that only contain PHP code is not recommended as you might accidentally add whitespace after the closing tag which would then be output by PHP. This can cause severe problems, for example headers cannot be sent anymore.

A simple precaution is to leave off the closing tag as it is not required, and it also has no negative effects whatsoever.

Loading history...
766