Test Failed
Push — master ( 46554f...425978 )
by
unknown
22:04 queued 01:06
created

OutOfOfficeSettingsModule::saveOofSettings()   C

Complexity

Conditions 15
Paths 40

Size

Total Lines 31
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 4
Bugs 0 Features 0
Metric Value
cc 15
eloc 17
c 4
b 0
f 0
nc 40
nop 1
dl 0
loc 31
rs 5.9166

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/**
4
 * OutOfOfficeSettingsModule Module.
5
 */
6
class OutOfOfficeSettingsModule extends Module {
7
	/**
8
	 * Constructor.
9
	 *
10
	 * @param int   $id   unique id
11
	 * @param array $data list of all actions
12
	 */
13
	public function __construct($id, $data) {
14
		parent::__construct($id, $data);
15
16
		$this->properties = $GLOBALS["properties"]->getOutOfOfficeProperties();
0 ignored issues
show
Bug Best Practice introduced by
The property properties does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
17
	}
18
19
	/**
20
	 * Executes all the actions in the $data variable.
21
	 */
22
	public function execute() {
23
		foreach ($this->data as $actionType => $action) {
24
			if (isset($actionType)) {
25
				try {
26
					switch ($actionType) {
27
						case "list" :
28
							$this->getOofSettings();
29
							break;
30
31
						case "save" :
32
							$this->saveOofSettings($action);
33
							break;
34
35
						default:
36
							$this->handleUnknownActionType($actionType);
37
					}
38
				}
39
				catch (SettingsException $e) {
40
					$this->processException($e, $actionType);
41
				}
42
				catch (MAPIException $e) {
43
					$this->processException($e, $actionType);
44
				}
45
			}
46
		}
47
	}
48
49
	/**
50
	 * Read 'out of office' settings from PR_EC_OUTOFOFFICE_*.
51
	 *
52
	 * Internal function to retrieve the 'out of office' settings from the store, these settings are normal properties on the store
53
	 */
54
	public function getOofSettings() {
55
		$otherStores = $this->getOwnerPermissionStores();
56
		array_unshift($otherStores, $GLOBALS['mapisession']->getDefaultMessageStore());
57
58
		$oofSettings = [];
59
		foreach ($otherStores as $storeEntryId => $storeObj) {
60
			$props = mapi_getprops($storeObj, $this->properties);
61
			if (!isset($props[PR_EC_OUTOFOFFICE])) {
62
				$props[PR_EC_OUTOFOFFICE] = false;
63
			}
64
			if (!isset($props[PR_EC_OUTOFOFFICE_MSG])) {
65
				$props[PR_EC_OUTOFOFFICE_MSG] = '';
66
			}
67
			if (!isset($props[PR_EC_OUTOFOFFICE_SUBJECT])) {
68
				$props[PR_EC_OUTOFOFFICE_SUBJECT] = '';
69
			}
70
			if (!isset($props[PR_EC_OUTOFOFFICE_FROM])) {
71
				$props[PR_EC_OUTOFOFFICE_FROM] = 0;
72
			}
73
			if (!isset($props[PR_EC_OUTOFOFFICE_UNTIL]) || $props[PR_EC_OUTOFOFFICE_UNTIL] === FUTURE_ENDDATE) {
74
				$props[PR_EC_OUTOFOFFICE_UNTIL] = 0;
75
			}
76
			if (!isset($props[PR_EC_ALLOW_EXTERNAL])) {
77
				$props[PR_EC_ALLOW_EXTERNAL] = 0;
78
			}
79
			if (!isset($props[PR_EC_EXTERNAL_AUDIENCE])) {
80
				$props[PR_EC_EXTERNAL_AUDIENCE] = 0;
81
			}
82
			if (!isset($props[PR_EC_EXTERNAL_REPLY])) {
83
				$props[PR_EC_EXTERNAL_REPLY] = '';
84
			}
85
			if (!isset($props[PR_EC_EXTERNAL_SUBJECT])) {
86
				$props[PR_EC_EXTERNAL_SUBJECT] = '';
87
			}
88
89
			$externalProps['props']['entryid'] = bin2hex($props[PR_MAILBOX_OWNER_ENTRYID]);
90
			$externalProps['props']['store_entryid'] = bin2hex($props[PR_ENTRYID]);
91
			$externalProps['props']['set'] = $props[PR_EC_OUTOFOFFICE];
92
			$externalProps['props']['internal_reply'] = trim($props[PR_EC_OUTOFOFFICE_MSG]);
93
			$externalProps['props']['internal_subject'] = trim($props[PR_EC_OUTOFOFFICE_SUBJECT]);
94
			$externalProps['props']['from'] = $props[PR_EC_OUTOFOFFICE_FROM];
95
			$externalProps['props']['until'] = $props[PR_EC_OUTOFOFFICE_UNTIL];
96
			$externalProps['props']['allow_external'] = $props[PR_EC_ALLOW_EXTERNAL];
97
			$externalProps['props']['external_audience'] = $props[PR_EC_EXTERNAL_AUDIENCE];
98
			$externalProps['props']['external_reply'] = trim($props[PR_EC_EXTERNAL_REPLY]);
99
			$externalProps['props']['external_subject'] = trim($props[PR_EC_EXTERNAL_SUBJECT]);
100
101
			array_push($oofSettings, $externalProps);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $externalProps seems to be defined later in this foreach loop on line 89. Are you sure it is defined here?
Loading history...
102
		}
103
104
		// Send success message to client
105
		$this->addActionData('list', ['item' => $oofSettings]);
106
107
		$GLOBALS["bus"]->addData($this->getResponseData());
108
	}
109
110
	/**
111
	 * Function returns array of user stores who has given 'Owner' permission to logged in user.
112
	 * Internal function to retrieve the shared stores with 'owner' permission.
113
	 *
114
	 * @return {Array} array of user stores who has given 'owner' permission
0 ignored issues
show
Documentation Bug introduced by
The doc comment {Array} at position 0 could not be parsed: Unknown type name '{' at position 0 in {Array}.
Loading history...
115
	 */
116
	public function getOwnerPermissionStores() {
117
		$stores = $GLOBALS['mapisession']->getOtherUserStore();
118
119
		// $sharedOwnerStores array will contains store of users who has given 'owner' permission.
120
		// Or store of users which can be fully accessible by default user in case of 'Admin User'.
121
		$sharedOwnerStores = [];
122
123
		foreach ($stores as $storeEntryId => $storeObj) {
124
			$subTree = mapi_getprops($storeObj, [PR_IPM_SUBTREE_ENTRYID]);
125
126
			try {
127
				$subtreeObj = mapi_msgstore_openentry($storeObj, $subTree[PR_IPM_SUBTREE_ENTRYID]);
128
			}
129
			catch (MAPIException $e) {
130
				// we don't have rights to open folder, so don't include User's store.
131
				if ($e->getCode() === MAPI_E_NO_ACCESS) {
132
					continue;
133
				}
134
135
				// rethrow other errors
136
				throw $e;
137
			}
138
139
			$permission = mapi_getprops($subtreeObj, [PR_RIGHTS]);
140
			$hasSufficientPermission = $permission[PR_RIGHTS] & ecRightsSecretary === ecRightsSecretary;
141
142
			// If User store's IPM subtree has rights higher than 'secretary' then include that User's store.
143
			if ($hasSufficientPermission) {
144
				$sharedOwnerStores[$storeEntryId] = $storeObj;
145
			}
146
		}
147
148
		return $sharedOwnerStores;
149
	}
150
151
	/**
152
	 * Internal function to save the 'out of office' settings to the correct properties on the store.
153
	 * On success function will send 'success' feedback to user.
154
	 *
155
	 * Writes some properties to the PR_EC_OUTOFOFFICE_* properties
156
	 *
157
	 * @param array $action the action data, sent by the client
158
	 */
159
	public function saveOofSettings($action) {
160
		$storeEntryId = $action['store_entryid'];
161
		$oofSettings = $action['props'];
162
		$store = $GLOBALS['mapisession']->openMessageStore(hex2bin($storeEntryId));
163
		$props = Conversion::mapXML2MAPI($this->properties, $oofSettings);
164
		$oofProps = mapi_getprops($store, [PR_EC_OUTOFOFFICE, PR_EC_OUTOFOFFICE_FROM, PR_EC_OUTOFOFFICE_UNTIL]);
165
166
		// If client sent until value as 0 or User set OOF to true but don't set until
167
		// then save FUTURE_ENDDATE as until date. Also when OOF is already ON and User
168
		// don't change 'until' field then check if 'until' value is available in User's store
169
		// and if not then set until date to FUTURE_ENDDATE.
170
		// Note: If we remove PR_EC_OUTOFOFFICE_UNTIL property from User's store,
171
		// then gromox is setting past value "1970-01-01 00:00:00" as until date.
172
		// To avoid this issue and for OOF to work as expected, we are setting until date as FUTURE_ENDDATE.
173
		if (isset($oofSettings['until']) && $oofSettings['until'] === 0 ||
174
			!isset($oofSettings['until']) && isset($oofSettings['set']) ||
175
			(!isset($oofSettings['until'], $oofSettings['set']) &&
176
				(!isset($oofProps[PR_EC_OUTOFOFFICE_UNTIL]) || $oofProps[PR_EC_OUTOFOFFICE_UNTIL] === 0))) {
177
			$props[$this->properties['until']] = FUTURE_ENDDATE;
178
		}
179
180
		// Check if the OOF is set for the future
181
		$oofSet = (isset($oofSettings['set']) && $oofSettings['set']) || (!isset($oofSettings['set']) && $oofProps[PR_EC_OUTOFOFFICE]);
182
		if ($oofSet && isset($oofSettings['from']) && intval($oofSettings['from']) > time()) {
183
			$props[$this->properties['set']] = 2;
184
		}
185
		if (!empty($props)) {
186
			mapi_setprops($store, $props);
187
			mapi_savechanges($store);
188
		}
189
		$this->sendFeedback(true);
190
	}
191
}
192