grommunio /
grommunio-web
| 1 | <?php |
||
| 2 | /** |
||
| 3 | * Addressbook Module |
||
| 4 | */ |
||
| 5 | class AddressbookListModule extends ListModule |
||
| 6 | { |
||
| 7 | /** |
||
| 8 | * Constructor |
||
| 9 | * @param int $id unique id. |
||
| 10 | * @param array $data list of all actions. |
||
| 11 | */ |
||
| 12 | function __construct($id, $data) |
||
| 13 | { |
||
| 14 | $this->properties = $GLOBALS['properties']->getAddressBookListProperties(); |
||
| 15 | |||
| 16 | parent::__construct($id, $data); |
||
| 17 | } |
||
| 18 | |||
| 19 | /** |
||
| 20 | * Creates the notifiers for this module, |
||
| 21 | * and register them to the Bus. |
||
| 22 | */ |
||
| 23 | function createNotifiers() |
||
| 24 | { |
||
| 25 | $GLOBALS["bus"]->registerNotifier('addressbooknotifier', ADDRESSBOOK_ENTRYID); |
||
| 26 | } |
||
| 27 | |||
| 28 | /** |
||
| 29 | * Executes all the actions in the $data variable. |
||
| 30 | * @return boolean true on success of false on fialure. |
||
| 31 | */ |
||
| 32 | function execute() |
||
| 33 | { |
||
| 34 | foreach($this->data as $actionType => $action) |
||
| 35 | { |
||
| 36 | if(isset($actionType)) { |
||
| 37 | try { |
||
| 38 | $store = $this->getActionStore($action); |
||
| 39 | $parententryid = $this->getActionParentEntryID($action); |
||
| 40 | $entryid = $this->getActionEntryID($action); |
||
| 41 | |||
| 42 | if(isset($action['subActionType']) && $action['subActionType'] != '') { |
||
| 43 | $subActionType = $action['subActionType']; |
||
| 44 | } |
||
| 45 | |||
| 46 | switch($actionType) |
||
| 47 | { |
||
| 48 | case 'list': |
||
| 49 | switch($subActionType) |
||
| 50 | { |
||
| 51 | case 'hierarchy': |
||
| 52 | $this->getHierarchy($action); |
||
| 53 | break; |
||
| 54 | case 'globaladdressbook': |
||
| 55 | $this->GABUsers($action, $subActionType); |
||
| 56 | break; |
||
| 57 | default: |
||
| 58 | $this->handleUnknownActionType($actionType); |
||
| 59 | } |
||
| 60 | break; |
||
| 61 | default: |
||
| 62 | $this->handleUnknownActionType($actionType); |
||
| 63 | } |
||
| 64 | } catch (MAPIException $e) { |
||
| 65 | $this->processException($e, $actionType, $store, $parententryid, $entryid, $action); |
||
| 66 | } |
||
| 67 | } |
||
| 68 | } |
||
| 69 | } |
||
| 70 | |||
| 71 | /** |
||
| 72 | * Function which retrieves the list of system users in Zarafa. |
||
| 73 | * @param object $store MAPI Message Store Object |
||
| 74 | * @param array $action the action data, sent by the client |
||
| 75 | * @param string $actionType the action type, sent by the client |
||
| 76 | * @return boolean true on success or false on failure |
||
| 77 | */ |
||
| 78 | function GABUsers($action, $actionType) |
||
| 79 | { |
||
| 80 | $searchstring = ''; |
||
| 81 | $hide_users = false; |
||
| 82 | $hide_groups = false; |
||
| 83 | $hide_companies = false; |
||
| 84 | |||
| 85 | if(isset($action['restriction'])) { |
||
| 86 | if(isset($action['restriction']['searchstring'])) { |
||
| 87 | // Get search string for searching in AB. |
||
| 88 | $searchstring = $action['restriction']['searchstring']; |
||
| 89 | } |
||
| 90 | |||
| 91 | if(isset($action['restriction']['hide_users'])) { |
||
| 92 | $hide_users = $action['restriction']['hide_users']; |
||
| 93 | } |
||
| 94 | if(isset($action['restriction']['hide_groups'])) { |
||
| 95 | $hide_groups = $action['restriction']['hide_groups']; |
||
| 96 | } |
||
| 97 | if(isset($action['restriction']['hide_companies'])) { |
||
| 98 | $hide_companies = $action['restriction']['hide_companies']; |
||
| 99 | } |
||
| 100 | } |
||
| 101 | |||
| 102 | $items = array(); |
||
| 103 | |||
| 104 | $data['page'] = array(); |
||
| 105 | $data['page']['start'] = 0; |
||
| 106 | $data['page']['rowcount'] = 0; |
||
| 107 | $data['page']['totalrowcount'] = 0; |
||
| 108 | |||
| 109 | $data = array(); |
||
| 110 | |||
| 111 | $this->sort = array(); |
||
| 112 | |||
| 113 | $map = array(); |
||
| 114 | $map['fileas'] = $this->properties['account']; |
||
| 115 | |||
| 116 | // Rewrite the sort info when sorting on full name as this is a combination of multiple fields |
||
| 117 | global $sortingField; |
||
| 118 | if ( isset($action["sort"]) && is_array($action["sort"]) && count($action["sort"])===1 && isset($action["sort"][0]["field"])) { |
||
| 119 | $sortingDir = $action["sort"][0]["direction"]; |
||
| 120 | $sortingField = $action["sort"][0]["field"]; |
||
| 121 | if($action["sort"][0]["field"] === 'full_name') { |
||
| 122 | $action["sort"] = array( |
||
| 123 | array( |
||
| 124 | "field" => "surname", |
||
| 125 | "direction" => $sortingDir |
||
| 126 | ), |
||
| 127 | array( |
||
| 128 | "field" => "given_name", |
||
| 129 | "direction" => $sortingDir |
||
| 130 | ), |
||
| 131 | array( |
||
| 132 | "field" => "middle_name", |
||
| 133 | "direction" => $sortingDir |
||
| 134 | ), |
||
| 135 | array( |
||
| 136 | "field" => "display_name", |
||
| 137 | "direction" => $sortingDir |
||
| 138 | ), |
||
| 139 | ); |
||
| 140 | } |
||
| 141 | |||
| 142 | // Parse incoming sort order |
||
| 143 | $this->parseSortOrder($action, $map, true); |
||
| 144 | } |
||
| 145 | |||
| 146 | $folderType = $action['folderType']; |
||
| 147 | |||
| 148 | if (($folderType!=='gab' || ENABLE_FULL_GAB) || !empty($searchstring)) { |
||
| 149 | $ab = $GLOBALS['mapisession']->getAddressbook(false, true); |
||
| 150 | |||
| 151 | if (!empty($action['entryid'])) { |
||
| 152 | $entryid = hex2bin($action['entryid']); |
||
| 153 | } else { |
||
| 154 | $entryid = mapi_ab_getdefaultdir($ab); |
||
| 155 | } |
||
| 156 | |||
| 157 | $dir = mapi_ab_openentry($ab,$entryid); |
||
| 158 | |||
| 159 | /** |
||
| 160 | * @TODO: 'All Address Lists' on IABContainer gives MAPI_E_INVALID_PARAMETER, |
||
| 161 | * as it contains subfolders only. When #7344 is fixed, MAPI will return error here, |
||
| 162 | * handle it here and return false. |
||
| 163 | */ |
||
| 164 | $table = mapi_folder_getcontentstable($dir, MAPI_DEFERRED_ERRORS); |
||
| 165 | |||
| 166 | $restriction = false; |
||
| 167 | $tempRestriction = false; |
||
| 168 | $userGroupRestriction = false; |
||
| 169 | |||
| 170 | if($hide_users || $hide_groups || $hide_companies) { |
||
| 171 | $userRestrictions = array(); |
||
| 172 | if ($hide_users) { |
||
| 173 | $tmp = $this->createUsersRestriction($hide_users); |
||
| 174 | if ($tmp) { |
||
| 175 | $userRestrictions[] = $tmp; |
||
| 176 | } |
||
| 177 | } |
||
| 178 | if ($hide_groups) { |
||
| 179 | $tmp = $this->createGroupsRestriction($hide_groups); |
||
| 180 | if ($tmp) { |
||
| 181 | $userRestrictions[] = $tmp; |
||
| 182 | } |
||
| 183 | } |
||
| 184 | if ($hide_companies) { |
||
| 185 | $tmp = $this->createCompanyRestriction($hide_companies); |
||
| 186 | if ($tmp) { |
||
| 187 | $userRestrictions[] = $tmp; |
||
| 188 | } |
||
| 189 | } |
||
| 190 | $userGroupRestriction = Array(RES_AND, $userRestrictions); |
||
| 191 | } |
||
| 192 | |||
| 193 | if(!empty($searchstring)){ |
||
| 194 | // create restriction for search |
||
| 195 | // only return users from who the displayName or the username starts with $searchstring |
||
| 196 | // TODO: use PR_ANR for this restriction instead of PR_DISPLAY_NAME and PR_ACCOUNT |
||
| 197 | $tempRestriction = array(RES_OR, |
||
| 198 | array( |
||
| 199 | // Display name of user from GAB and contacts. |
||
| 200 | array( |
||
| 201 | RES_CONTENT, |
||
| 202 | array(FUZZYLEVEL => FL_SUBSTRING|FL_IGNORECASE, |
||
| 203 | ULPROPTAG => PR_DISPLAY_NAME, |
||
| 204 | VALUE => $searchstring |
||
| 205 | ) |
||
| 206 | ), |
||
| 207 | // fileas value of user from GAB. |
||
| 208 | array( |
||
| 209 | RES_CONTENT, |
||
| 210 | array(FUZZYLEVEL => FL_SUBSTRING|FL_IGNORECASE, |
||
| 211 | ULPROPTAG => PR_ACCOUNT, |
||
| 212 | VALUE => $searchstring |
||
| 213 | ) |
||
| 214 | ), |
||
| 215 | // smtp_address of user from GAB. |
||
| 216 | array( |
||
| 217 | RES_CONTENT, |
||
| 218 | array(FUZZYLEVEL => FL_SUBSTRING|FL_IGNORECASE, |
||
| 219 | ULPROPTAG => PR_SMTP_ADDRESS, |
||
| 220 | VALUE => $searchstring |
||
| 221 | ) |
||
| 222 | ), |
||
| 223 | // email_address of user from GAB and contacts. |
||
| 224 | array( |
||
| 225 | RES_CONTENT, |
||
| 226 | array(FUZZYLEVEL => FL_SUBSTRING|FL_IGNORECASE, |
||
| 227 | ULPROPTAG => PR_EMAIL_ADDRESS, |
||
| 228 | VALUE => $searchstring |
||
| 229 | ) |
||
| 230 | ), |
||
| 231 | // department of user from GAB. |
||
| 232 | array( |
||
| 233 | RES_CONTENT, |
||
| 234 | array(FUZZYLEVEL => FL_SUBSTRING|FL_IGNORECASE, |
||
| 235 | ULPROPTAG => PR_DEPARTMENT_NAME, |
||
| 236 | VALUE => $searchstring |
||
| 237 | ) |
||
| 238 | ), |
||
| 239 | // fileas of user from Contacts. |
||
| 240 | array( |
||
| 241 | RES_CONTENT, |
||
| 242 | array(FUZZYLEVEL => FL_SUBSTRING|FL_IGNORECASE, |
||
| 243 | ULPROPTAG => PR_ORIGINAL_DISPLAY_NAME, |
||
| 244 | VALUE => $searchstring |
||
| 245 | ) |
||
| 246 | ) |
||
| 247 | ) |
||
| 248 | ); |
||
| 249 | } |
||
| 250 | |||
| 251 | if($tempRestriction && $userGroupRestriction) { |
||
| 252 | $restriction = Array( |
||
| 253 | RES_AND, |
||
| 254 | Array( |
||
| 255 | // restriction for search/alphabet bar |
||
| 256 | $tempRestriction, |
||
| 257 | // restriction for hiding users/groups |
||
| 258 | $userGroupRestriction, |
||
| 259 | )); |
||
| 260 | } else if($tempRestriction) { |
||
| 261 | // restriction for search/alphabet bar |
||
| 262 | $restriction = $tempRestriction; |
||
| 263 | } else { |
||
| 264 | // restriction for hiding users/groups |
||
| 265 | $restriction = $userGroupRestriction; |
||
| 266 | } |
||
| 267 | |||
| 268 | // Only add restriction when it is used |
||
| 269 | if($restriction) { |
||
| 270 | mapi_table_restrict($table, $restriction, TBL_BATCH); |
||
| 271 | } |
||
| 272 | // Only sort when asked for |
||
| 273 | if ( !empty($this->sort) ) { |
||
| 274 | mapi_table_sort($table, $this->sort, TBL_BATCH); |
||
| 275 | } |
||
| 276 | |||
| 277 | $rowCount = mapi_table_getrowcount($table); |
||
| 278 | |||
| 279 | if ( is_int(MAX_GAB_RESULTS) && MAX_GAB_RESULTS > 0 && $rowCount > MAX_GAB_RESULTS ) { |
||
| 280 | // Create a response that contains an error message that there are too much results |
||
| 281 | $data['error'] = array('code' => 'listexceederror', 'max_gab_users' => MAX_GAB_RESULTS); |
||
| 282 | $rows = mapi_table_queryrows($table, $this->properties, 0, MAX_GAB_RESULTS); |
||
| 283 | $rowCount = MAX_GAB_RESULTS; |
||
| 284 | } else { |
||
| 285 | $rows = mapi_table_queryallrows($table, $this->properties); |
||
| 286 | } |
||
| 287 | |||
| 288 | $sharedStore = null; |
||
| 289 | if (isset($action["isSharedFolder"]) && $action["isSharedFolder"] === true) { |
||
| 290 | if(isset($action["sharedFolder"]) && !empty($action["sharedFolder"])) { |
||
| 291 | $sharedStoreEntryID = $action["sharedFolder"]["store_entryid"]; |
||
| 292 | $sharedStore = $GLOBALS["mapisession"]->openMessageStore(hex2bin($sharedStoreEntryID)); |
||
| 293 | } |
||
| 294 | } |
||
| 295 | |||
| 296 | for ($i = 0, $len = $rowCount; $i < $len; $i++) { |
||
| 297 | // Use array_shift to so we won't double memory usage! |
||
| 298 | $user_data = array_shift($rows); |
||
| 299 | $item = array(); |
||
| 300 | $item['entryid'] = bin2hex($user_data[$this->properties['entryid']]); |
||
| 301 | $item['display_name'] = isset($user_data[$this->properties['display_name']]) ? $user_data[$this->properties['display_name']] : ""; |
||
| 302 | $item['object_type'] = isset($user_data[$this->properties['object_type']]) ? $user_data[$this->properties['object_type']] : ""; |
||
| 303 | $item['display_type'] = isset($user_data[PR_DISPLAY_TYPE]) ? $user_data[PR_DISPLAY_TYPE] : ""; |
||
| 304 | $item['title'] = isset($user_data[PR_TITLE]) ? $user_data[PR_TITLE] : ""; |
||
| 305 | $item['company_name'] = isset($user_data[PR_COMPANY_NAME]) ? $user_data[PR_COMPANY_NAME] : ""; |
||
| 306 | |||
| 307 | // Test whether the GUID in the entryid is from the Contact Provider |
||
| 308 | if($GLOBALS['entryid']->hasContactProviderGUID( bin2hex($user_data[$this->properties['entryid']]) )){ |
||
| 309 | // Use the original_display_name property to fill in the fileas column |
||
| 310 | $item['fileas'] = $user_data[$this->properties['original_display_name']] ?? $item['display_name']; |
||
| 311 | $item['address_type'] = isset($user_data[$this->properties['address_type']]) ? $user_data[$this->properties['address_type']] : 'SMTP'; |
||
| 312 | |||
| 313 | if (isset($action["isSharedFolder"]) && $action["isSharedFolder"] === true) { |
||
| 314 | if(isset($action["sharedFolder"]) && !empty($action["sharedFolder"])) { |
||
| 315 | $sharedContactEntryID = $GLOBALS['entryid']->unwrapABEntryIdObj(bin2hex($user_data[$this->properties['entryid']])); |
||
| 316 | // Address book record does not have 'private' property so we need to open shared contact to |
||
| 317 | // get the value of 'private' property. |
||
| 318 | $contact = $GLOBALS['operations']->openMessage($sharedStore, hex2bin($sharedContactEntryID)); |
||
| 319 | $sharedContactProps = mapi_getprops($contact, array($this->properties['private'])); |
||
| 320 | // Don't show the private contact. |
||
| 321 | if (isset($sharedContactProps[$this->properties['private']]) && $sharedContactProps[$this->properties['private']] === true) { |
||
| 322 | continue; |
||
| 323 | } |
||
| 324 | } |
||
| 325 | } |
||
| 326 | |||
| 327 | switch($user_data[PR_DISPLAY_TYPE]){ |
||
| 328 | case DT_PRIVATE_DISTLIST: |
||
| 329 | $item['email_address'] = ''; |
||
| 330 | break; |
||
| 331 | case DT_MAILUSER: |
||
| 332 | default: |
||
| 333 | $item['email_address'] = $user_data[$this->properties['email_address']]; |
||
| 334 | } |
||
| 335 | } else { |
||
| 336 | // If display_type_ex is not set we can overwrite it with display_type |
||
| 337 | $item['display_type_ex'] = isset($user_data[PR_DISPLAY_TYPE_EX])?$user_data[PR_DISPLAY_TYPE_EX]:$user_data[PR_DISPLAY_TYPE]; |
||
| 338 | $item['fileas'] = $item['display_name']; |
||
| 339 | $item['mobile_telephone_number'] = isset($user_data[PR_MOBILE_TELEPHONE_NUMBER])? $user_data[PR_MOBILE_TELEPHONE_NUMBER] : ''; |
||
| 340 | $item['home_telephone_number'] = isset($user_data[PR_HOME_TELEPHONE_NUMBER])? $user_data[PR_HOME_TELEPHONE_NUMBER] : ''; |
||
| 341 | $item['pager_telephone_number'] = isset($user_data[PR_PAGER_TELEPHONE_NUMBER])? $user_data[PR_PAGER_TELEPHONE_NUMBER] : ''; |
||
| 342 | $item['surname'] = isset($user_data[PR_SURNAME])? $user_data[PR_SURNAME] : ''; |
||
| 343 | $item['given_name'] = isset($user_data[$this->properties['given_name']])? $user_data[$this->properties['given_name']] : ''; |
||
| 344 | |||
| 345 | switch($user_data[PR_DISPLAY_TYPE]){ |
||
| 346 | case DT_ORGANIZATION: |
||
| 347 | $item['email_address'] = $user_data[$this->properties['account']]; |
||
| 348 | $item['address_type'] = 'EX'; |
||
| 349 | // The account property is used to fill in the fileas column |
||
| 350 | $item['fileas'] = $user_data[$this->properties['account']]; |
||
| 351 | break; |
||
| 352 | |||
| 353 | case DT_DISTLIST: |
||
| 354 | // The account property is used to fill in the fileas column, private dislist does not have that |
||
| 355 | $item['fileas'] = $user_data[$this->properties['account']]; |
||
| 356 | case DT_PRIVATE_DISTLIST: |
||
| 357 | $item['email_address'] = $user_data[$this->properties['account']]; |
||
| 358 | // FIXME: shouldn't be needed, but atm this gives us an undefined offset error which makes the unittests fail. |
||
| 359 | if($item['email_address'] !== 'Everyone') { |
||
| 360 | if (isset($user_data[$this->properties['smtp_address']])) { |
||
| 361 | $item['smtp_address'] = $user_data[$this->properties['smtp_address']]; |
||
| 362 | } |
||
| 363 | } |
||
| 364 | $item['address_type'] = 'EX'; |
||
| 365 | break; |
||
| 366 | |||
| 367 | case DT_MAILUSER: |
||
| 368 | // The account property is used to fill in the fileas column, remote mailuser does not have that |
||
| 369 | $item['fileas'] = $user_data[$this->properties['account']]; |
||
| 370 | case DT_REMOTE_MAILUSER: |
||
| 371 | default: |
||
| 372 | $item['email_address'] = $user_data[$this->properties['email_address']]; |
||
| 373 | $item['smtp_address'] = $user_data[$this->properties['smtp_address']]; |
||
| 374 | |||
| 375 | $item['address_type'] = isset($user_data[$this->properties['address_type']]) ? $user_data[$this->properties['address_type']] : 'SMTP'; |
||
| 376 | $item['department_name'] = isset($user_data[$this->properties['department_name']]) ? $user_data[$this->properties['department_name']] : ''; |
||
| 377 | $item['office_telephone_number'] = isset($user_data[$this->properties['office_telephone_number']]) ? $user_data[$this->properties['office_telephone_number']] : ''; |
||
| 378 | $item['office_location'] = isset($user_data[$this->properties['office_location']]) ? $user_data[$this->properties['office_location']] : ''; |
||
| 379 | $item['primary_fax_number'] = isset($user_data[$this->properties['primary_fax_number']]) ? $user_data[$this->properties['primary_fax_number']] : ''; |
||
| 380 | break; |
||
| 381 | } |
||
| 382 | } |
||
| 383 | |||
| 384 | // Create a nice full_name prop ("Lastname, Firstname Middlename") |
||
| 385 | if ( isset($user_data[$this->properties['surname']]) ){ |
||
| 386 | $item['full_name'] = $user_data[$this->properties['surname']]; |
||
| 387 | } else { |
||
| 388 | $item['full_name'] = ''; |
||
| 389 | } |
||
| 390 | if ( (isset($user_data[$this->properties['given_name']]) || isset($user_data[$this->properties['middle_name']])) && !empty($item['full_name']) ){ |
||
| 391 | $item['full_name'] .= ', '; |
||
| 392 | } |
||
| 393 | if ( isset($user_data[$this->properties['given_name']]) ){ |
||
| 394 | $item['full_name'] .= $user_data[$this->properties['given_name']]; |
||
| 395 | } |
||
| 396 | if ( isset($user_data[$this->properties['middle_name']]) ){ |
||
| 397 | $item['full_name'] .= ' ' . $user_data[$this->properties['middle_name']]; |
||
| 398 | } |
||
| 399 | if ( empty($item['full_name']) ){ |
||
| 400 | $item['full_name'] = $item['display_name']; |
||
| 401 | } |
||
| 402 | |||
| 403 | if(!empty($user_data[$this->properties['search_key']])) { |
||
| 404 | $item['search_key'] = bin2hex($user_data[$this->properties['search_key']]); |
||
| 405 | } else { |
||
| 406 | // contacts folders are not returning search keys, this should be fixed in Gromox |
||
| 407 | // meanwhile this is a workaround, check ZCP-10814 |
||
| 408 | // if search key is not passed then we will generate it |
||
| 409 | $email_address = ''; |
||
| 410 | if(!empty($item['smtp_address'])) { |
||
| 411 | $email_address = $item['smtp_address']; |
||
| 412 | } else if(!empty($item['email_address'])) { |
||
| 413 | $email_address = $item['email_address']; |
||
| 414 | } |
||
| 415 | |||
| 416 | if(!empty($email_address)) { |
||
| 417 | $item['search_key'] = bin2hex(strtoupper($item['address_type'] . ':' . $email_address)) . '00'; |
||
| 418 | } |
||
| 419 | } |
||
| 420 | |||
| 421 | array_push($items, array('props' => $item)); |
||
| 422 | } |
||
| 423 | |||
| 424 | if ( !empty($sortingField) ){ |
||
| 425 | // Sort the items here, because full_name is not a real property, so we can not use the regular sorting |
||
| 426 | // Note: This hack only works because the GAB does not work with paging! |
||
| 427 | function cmpAsc($a, $b){ |
||
| 428 | global $sortingField; |
||
| 429 | return strcasecmp($b['props'][$sortingField], $a['props'][$sortingField]); |
||
| 430 | } |
||
| 431 | function cmpDesc($a, $b){ |
||
| 432 | global $sortingField; |
||
| 433 | return strcasecmp($a['props'][$sortingField], $b['props'][$sortingField]); |
||
| 434 | } |
||
| 435 | |||
| 436 | $cmpFn = $sortingDir === 'DESC' ? 'cmpDesc' : 'cmpAsc'; |
||
| 437 | usort($items, $cmpFn); |
||
| 438 | } |
||
| 439 | |||
| 440 | // todo: fix paging stuff |
||
| 441 | $data['page']['start'] = 0; |
||
| 442 | $data['page']['rowcount'] = $rowCount; |
||
| 443 | $data['page']['totalrowcount'] = $data['page']['rowcount']; |
||
| 444 | $data = array_merge($data, array('item'=>$items)); |
||
| 445 | } else { |
||
| 446 | // Provide clue that full GAB is disabled. |
||
| 447 | $data = array_merge($data, array('disable_full_gab' => !ENABLE_FULL_GAB)); |
||
| 448 | } |
||
| 449 | |||
| 450 | $this->addActionData('list', $data); |
||
| 451 | $GLOBALS['bus']->addData($this->getResponseData()); |
||
| 452 | |||
| 453 | return true; |
||
| 454 | } |
||
| 455 | |||
| 456 | /** |
||
| 457 | * Function will create a restriction based on parameters passed for hiding users |
||
| 458 | * @param Array $hide_users list of users that should not be shown |
||
| 459 | * @return restrictionObject restriction for hiding provided users |
||
| 460 | */ |
||
| 461 | function createUsersRestriction($hide_users) { |
||
| 462 | $usersRestriction = null; |
||
| 463 | |||
| 464 | // When $hide_users is true, then we globally disable |
||
| 465 | // all users regardless of their subtype. Otherwise if |
||
| 466 | // $hide_users is set then we start looking which subtype |
||
| 467 | // is being filtered out. |
||
| 468 | if ($hide_users === true) { |
||
|
0 ignored issues
–
show
introduced
by
Loading history...
|
|||
| 469 | $usersRestriction = Array( |
||
| 470 | RES_AND, |
||
| 471 | Array( |
||
| 472 | Array( |
||
| 473 | RES_PROPERTY, |
||
| 474 | Array( |
||
| 475 | RELOP => RELOP_NE, |
||
| 476 | ULPROPTAG => PR_DISPLAY_TYPE, |
||
| 477 | VALUE => Array( |
||
| 478 | PR_DISPLAY_TYPE => DT_MAILUSER |
||
| 479 | ) |
||
| 480 | ) |
||
| 481 | ), |
||
| 482 | Array( |
||
| 483 | RES_PROPERTY, |
||
| 484 | Array( |
||
| 485 | RELOP => RELOP_NE, |
||
| 486 | ULPROPTAG => PR_DISPLAY_TYPE, |
||
| 487 | VALUE => Array( |
||
| 488 | PR_DISPLAY_TYPE => DT_REMOTE_MAILUSER |
||
| 489 | ) |
||
| 490 | ) |
||
| 491 | ) |
||
| 492 | ) |
||
| 493 | ); |
||
| 494 | } else if ($hide_users) { |
||
| 495 | $tempRestrictions = Array(); |
||
| 496 | |||
| 497 | // wrap parameters in an array |
||
| 498 | if(!is_array($hide_users)) { |
||
| 499 | $hide_users = Array($hide_users); |
||
| 500 | } |
||
| 501 | |||
| 502 | if(in_array('non_security', $hide_users)) { |
||
| 503 | array_push($tempRestrictions, Array( |
||
| 504 | RES_BITMASK, |
||
| 505 | Array( |
||
| 506 | ULTYPE => BMR_EQZ, |
||
| 507 | ULPROPTAG => PR_DISPLAY_TYPE_EX, |
||
| 508 | ULMASK => DTE_FLAG_ACL_CAPABLE |
||
| 509 | ) |
||
| 510 | ) |
||
| 511 | ); |
||
| 512 | } |
||
| 513 | |||
| 514 | if(in_array('room', $hide_users)) { |
||
| 515 | array_push($tempRestrictions, Array( |
||
| 516 | RES_PROPERTY, |
||
| 517 | Array( |
||
| 518 | RELOP => RELOP_EQ, |
||
| 519 | ULPROPTAG => PR_DISPLAY_TYPE_EX, |
||
| 520 | VALUE => Array( |
||
| 521 | PR_DISPLAY_TYPE_EX => DT_ROOM |
||
| 522 | ) |
||
| 523 | ) |
||
| 524 | ) |
||
| 525 | ); |
||
| 526 | } |
||
| 527 | |||
| 528 | if(in_array('equipment', $hide_users)) { |
||
| 529 | array_push($tempRestrictions, Array( |
||
| 530 | RES_PROPERTY, |
||
| 531 | Array( |
||
| 532 | RELOP => RELOP_EQ, |
||
| 533 | ULPROPTAG => PR_DISPLAY_TYPE_EX, |
||
| 534 | VALUE => Array( |
||
| 535 | PR_DISPLAY_TYPE_EX => DT_EQUIPMENT |
||
| 536 | ) |
||
| 537 | ) |
||
| 538 | ) |
||
| 539 | ); |
||
| 540 | } |
||
| 541 | |||
| 542 | if(in_array('active', $hide_users)) { |
||
| 543 | array_push($tempRestrictions, Array( |
||
| 544 | RES_PROPERTY, |
||
| 545 | Array( |
||
| 546 | RELOP => RELOP_EQ, |
||
| 547 | ULPROPTAG => PR_DISPLAY_TYPE_EX, |
||
| 548 | VALUE => Array( |
||
| 549 | PR_DISPLAY_TYPE_EX => DTE_FLAG_ACL_CAPABLE |
||
| 550 | ) |
||
| 551 | ) |
||
| 552 | ) |
||
| 553 | ); |
||
| 554 | } |
||
| 555 | |||
| 556 | if(in_array('non_active', $hide_users)) { |
||
| 557 | array_push($tempRestrictions, Array( |
||
| 558 | RES_PROPERTY, |
||
| 559 | Array( |
||
| 560 | RELOP => RELOP_EQ, |
||
| 561 | ULPROPTAG => PR_DISPLAY_TYPE_EX, |
||
| 562 | VALUE => Array( |
||
| 563 | PR_DISPLAY_TYPE_EX => DT_MAILUSER |
||
| 564 | ) |
||
| 565 | ) |
||
| 566 | ) |
||
| 567 | ); |
||
| 568 | } |
||
| 569 | |||
| 570 | if(in_array('contact', $hide_users)) { |
||
| 571 | array_push($tempRestrictions, Array( |
||
| 572 | RES_PROPERTY, |
||
| 573 | Array( |
||
| 574 | RELOP => RELOP_EQ, |
||
| 575 | ULPROPTAG => PR_DISPLAY_TYPE_EX, |
||
| 576 | VALUE => Array( |
||
| 577 | PR_DISPLAY_TYPE_EX => DT_REMOTE_MAILUSER |
||
| 578 | ) |
||
| 579 | ) |
||
| 580 | ) |
||
| 581 | ); |
||
| 582 | } |
||
| 583 | |||
| 584 | if(in_array('system', $hide_users)) { |
||
| 585 | array_push($tempRestrictions, Array( |
||
| 586 | RES_CONTENT, |
||
| 587 | Array( |
||
| 588 | FUZZYLEVEL => FL_FULLSTRING | FL_IGNORECASE, |
||
| 589 | ULPROPTAG => PR_ACCOUNT, |
||
| 590 | VALUE => Array( |
||
| 591 | PR_ACCOUNT => 'SYSTEM' |
||
| 592 | ) |
||
| 593 | ) |
||
| 594 | ) |
||
| 595 | ); |
||
| 596 | } |
||
| 597 | |||
| 598 | if(!empty($tempRestrictions)) { |
||
| 599 | $usersRestriction = Array( |
||
| 600 | RES_NOT, |
||
| 601 | Array( |
||
| 602 | Array( |
||
| 603 | RES_AND, |
||
| 604 | Array( |
||
| 605 | Array( |
||
| 606 | RES_OR, |
||
| 607 | Array( |
||
| 608 | Array( |
||
| 609 | RES_PROPERTY, |
||
| 610 | Array( |
||
| 611 | RELOP => RELOP_EQ, |
||
| 612 | ULPROPTAG => PR_DISPLAY_TYPE, |
||
| 613 | VALUE => Array( |
||
| 614 | PR_DISPLAY_TYPE => DT_MAILUSER |
||
| 615 | ) |
||
| 616 | ) |
||
| 617 | ), |
||
| 618 | Array( |
||
| 619 | RES_PROPERTY, |
||
| 620 | Array( |
||
| 621 | RELOP => RELOP_EQ, |
||
| 622 | ULPROPTAG => PR_DISPLAY_TYPE, |
||
| 623 | VALUE => Array( |
||
| 624 | PR_DISPLAY_TYPE => DT_REMOTE_MAILUSER |
||
| 625 | ) |
||
| 626 | ) |
||
| 627 | ) |
||
| 628 | ) |
||
| 629 | ), |
||
| 630 | Array( |
||
| 631 | RES_OR, |
||
| 632 | $tempRestrictions // all user restrictions |
||
| 633 | ) |
||
| 634 | ) |
||
| 635 | ) |
||
| 636 | ) |
||
| 637 | ); |
||
| 638 | } |
||
| 639 | } |
||
| 640 | |||
| 641 | return $usersRestriction; |
||
| 642 | } |
||
| 643 | |||
| 644 | /** |
||
| 645 | * Function will create a restriction based on parameters passed for hiding groups |
||
| 646 | * @param Array $hide_groups list of groups that should not be shown |
||
| 647 | * @return restrictionObject restriction for hiding provided users |
||
| 648 | */ |
||
| 649 | function createGroupsRestriction($hide_groups) { |
||
| 650 | $groupsRestriction = null; |
||
| 651 | |||
| 652 | // When $hide_groups is true, then we globally disable |
||
| 653 | // all groups regardless of their subtype. Otherwise if |
||
| 654 | // $hide_groups is set then we start looking which subtype |
||
| 655 | // is being filtered out. |
||
| 656 | if ($hide_groups === true) { |
||
|
0 ignored issues
–
show
|
|||
| 657 | $groupsRestriction = Array( |
||
| 658 | RES_AND, |
||
| 659 | Array( |
||
| 660 | Array( |
||
| 661 | RES_PROPERTY, |
||
| 662 | Array( |
||
| 663 | RELOP => RELOP_NE, |
||
| 664 | ULPROPTAG => PR_DISPLAY_TYPE, |
||
| 665 | VALUE => Array( |
||
| 666 | PR_DISPLAY_TYPE => DT_DISTLIST |
||
| 667 | ) |
||
| 668 | ) |
||
| 669 | ), |
||
| 670 | Array( |
||
| 671 | RES_PROPERTY, |
||
| 672 | Array( |
||
| 673 | RELOP => RELOP_NE, |
||
| 674 | ULPROPTAG => PR_DISPLAY_TYPE, |
||
| 675 | VALUE => Array( |
||
| 676 | PR_DISPLAY_TYPE => DT_PRIVATE_DISTLIST |
||
| 677 | ) |
||
| 678 | ) |
||
| 679 | ) |
||
| 680 | ) |
||
| 681 | ); |
||
| 682 | } else if($hide_groups) { |
||
| 683 | $tempRestrictions = Array(); |
||
| 684 | |||
| 685 | // wrap parameters in an array |
||
| 686 | if(!is_array($hide_groups)) { |
||
| 687 | $hide_groups = Array($hide_groups); |
||
| 688 | } |
||
| 689 | |||
| 690 | if(in_array('non_security', $hide_groups)) { |
||
| 691 | array_push($tempRestrictions, Array( |
||
| 692 | RES_BITMASK, |
||
| 693 | Array( |
||
| 694 | ULTYPE => BMR_EQZ, |
||
| 695 | ULPROPTAG => PR_DISPLAY_TYPE_EX, |
||
| 696 | ULMASK => DTE_FLAG_ACL_CAPABLE |
||
| 697 | ) |
||
| 698 | ) |
||
| 699 | ); |
||
| 700 | } |
||
| 701 | |||
| 702 | if(in_array('normal', $hide_groups)) { |
||
| 703 | array_push($tempRestrictions, Array( |
||
| 704 | RES_PROPERTY, |
||
| 705 | Array( |
||
| 706 | RELOP => RELOP_EQ, |
||
| 707 | ULPROPTAG => PR_DISPLAY_TYPE_EX, |
||
| 708 | VALUE => Array( |
||
| 709 | PR_DISPLAY_TYPE_EX => DT_DISTLIST |
||
| 710 | ) |
||
| 711 | ) |
||
| 712 | ) |
||
| 713 | ); |
||
| 714 | } |
||
| 715 | |||
| 716 | if(in_array('security', $hide_groups)) { |
||
| 717 | array_push($tempRestrictions, Array( |
||
| 718 | RES_PROPERTY, |
||
| 719 | Array( |
||
| 720 | RELOP => RELOP_EQ, |
||
| 721 | ULPROPTAG => PR_DISPLAY_TYPE_EX, |
||
| 722 | VALUE => Array( |
||
| 723 | PR_DISPLAY_TYPE_EX => (DT_SEC_DISTLIST | DTE_FLAG_ACL_CAPABLE) |
||
| 724 | ) |
||
| 725 | ) |
||
| 726 | ) |
||
| 727 | ); |
||
| 728 | } |
||
| 729 | |||
| 730 | if(in_array('dynamic', $hide_groups)) { |
||
| 731 | array_push($tempRestrictions, Array( |
||
| 732 | RES_PROPERTY, |
||
| 733 | Array( |
||
| 734 | RELOP => RELOP_EQ, |
||
| 735 | ULPROPTAG => PR_DISPLAY_TYPE_EX, |
||
| 736 | VALUE => Array( |
||
| 737 | PR_DISPLAY_TYPE_EX => DT_AGENT |
||
| 738 | ) |
||
| 739 | ) |
||
| 740 | ) |
||
| 741 | ); |
||
| 742 | } |
||
| 743 | |||
| 744 | if(in_array('distribution_list', $hide_groups)) { |
||
| 745 | array_push($tempRestrictions, Array( |
||
| 746 | RES_PROPERTY, |
||
| 747 | Array( |
||
| 748 | RELOP => RELOP_EQ, |
||
| 749 | ULPROPTAG => PR_DISPLAY_TYPE, |
||
| 750 | VALUE => Array( |
||
| 751 | PR_DISPLAY_TYPE => DT_PRIVATE_DISTLIST |
||
| 752 | ) |
||
| 753 | ) |
||
| 754 | ) |
||
| 755 | ); |
||
| 756 | } |
||
| 757 | |||
| 758 | if(in_array('everyone', $hide_groups)) { |
||
| 759 | array_push($tempRestrictions, Array( |
||
| 760 | RES_CONTENT, |
||
| 761 | Array( |
||
| 762 | FUZZYLEVEL => FL_FULLSTRING | FL_IGNORECASE, |
||
| 763 | ULPROPTAG => PR_ACCOUNT, |
||
| 764 | VALUE => Array( |
||
| 765 | PR_ACCOUNT => 'Everyone' |
||
| 766 | ) |
||
| 767 | ) |
||
| 768 | ) |
||
| 769 | ); |
||
| 770 | } |
||
| 771 | |||
| 772 | if(!empty($tempRestrictions)) { |
||
| 773 | $groupsRestriction = Array( |
||
| 774 | RES_NOT, |
||
| 775 | Array( |
||
| 776 | Array( |
||
| 777 | RES_AND, |
||
| 778 | Array( |
||
| 779 | Array( |
||
| 780 | RES_OR, |
||
| 781 | Array( |
||
| 782 | Array( |
||
| 783 | RES_PROPERTY, |
||
| 784 | Array( |
||
| 785 | RELOP => RELOP_EQ, |
||
| 786 | ULPROPTAG => PR_DISPLAY_TYPE, |
||
| 787 | VALUE => Array( |
||
| 788 | PR_DISPLAY_TYPE => DT_DISTLIST |
||
| 789 | ) |
||
| 790 | ) |
||
| 791 | ), |
||
| 792 | Array( |
||
| 793 | RES_PROPERTY, |
||
| 794 | Array( |
||
| 795 | RELOP => RELOP_EQ, |
||
| 796 | ULPROPTAG => PR_DISPLAY_TYPE, |
||
| 797 | VALUE => Array( |
||
| 798 | PR_DISPLAY_TYPE => DT_PRIVATE_DISTLIST |
||
| 799 | ) |
||
| 800 | ) |
||
| 801 | ) |
||
| 802 | ) |
||
| 803 | ), |
||
| 804 | Array( |
||
| 805 | RES_OR, |
||
| 806 | $tempRestrictions // all group restrictions |
||
| 807 | ) |
||
| 808 | ) |
||
| 809 | ) |
||
| 810 | ) |
||
| 811 | ); |
||
| 812 | } |
||
| 813 | } |
||
| 814 | |||
| 815 | return $groupsRestriction; |
||
| 816 | } |
||
| 817 | |||
| 818 | /** |
||
| 819 | * Function will create a restriction to get company information |
||
| 820 | * @param Boolean $hide_companies true/false |
||
| 821 | * @return restrictionObject restriction for getting company info |
||
| 822 | */ |
||
| 823 | function createCompanyRestriction($hide_companies) { |
||
| 824 | $companyRestriction = false; |
||
| 825 | |||
| 826 | if($hide_companies) { |
||
| 827 | $companyRestriction = Array( |
||
| 828 | RES_PROPERTY, |
||
| 829 | Array( |
||
| 830 | RELOP => RELOP_NE, |
||
| 831 | ULPROPTAG => PR_DISPLAY_TYPE, |
||
| 832 | VALUE => Array( |
||
| 833 | PR_DISPLAY_TYPE => DT_ORGANIZATION |
||
| 834 | ) |
||
| 835 | ) |
||
| 836 | ); |
||
| 837 | } |
||
| 838 | |||
| 839 | return $companyRestriction; |
||
| 840 | } |
||
| 841 | |||
| 842 | function getHierarchy($action) |
||
| 843 | { |
||
| 844 | $hideContacts = false; |
||
| 845 | // Check if hide_contacts is set in the restriction |
||
| 846 | if(isset($action['restriction']) && isset($action['restriction']['hide_contacts'])){ |
||
| 847 | $hideContacts = $action['restriction']['hide_contacts']; |
||
| 848 | } |
||
| 849 | |||
| 850 | $folders = $this->getAddressbookHierarchy($hideContacts); |
||
| 851 | $data = array( 'item' => $folders ); |
||
| 852 | $this->addActionData('list', $data); |
||
| 853 | $GLOBALS['bus']->addData($this->getResponseData()); |
||
| 854 | |||
| 855 | return true; |
||
| 856 | } |
||
| 857 | |||
| 858 | /** |
||
| 859 | * Get addressbook hierarchy |
||
| 860 | * |
||
| 861 | * This function returns the entire hierarchy of the addressbook, with global addressbooks, and contacts |
||
| 862 | * folders. |
||
| 863 | * |
||
| 864 | * The output array contains an associative array for each found contact folder. Each entry contains |
||
| 865 | * "display_name" => Name of the folder, "entryid" => entryid of the folder, "parent_entryid" => parent entryid |
||
| 866 | * "storeid" => store entryid, "type" => gab | contacts |
||
| 867 | * |
||
| 868 | * @param array Associative array with store information |
||
| 869 | * @return array Array of associative arrays with addressbook container information |
||
| 870 | * @todo Fix bizarre input parameter format |
||
| 871 | */ |
||
| 872 | function getAddressbookHierarchy($hideContacts = false) |
||
| 873 | { |
||
| 874 | $ab = $GLOBALS["mapisession"]->getAddressbook(false, true); |
||
| 875 | $dir = mapi_ab_openentry($ab); |
||
| 876 | $table = mapi_folder_gethierarchytable($dir, MAPI_DEFERRED_ERRORS | CONVENIENT_DEPTH); |
||
| 877 | |||
| 878 | if($hideContacts){ |
||
| 879 | // Restrict on the addressbook provider GUID if the contact folders need to be hidden |
||
| 880 | $restriction = array(RES_PROPERTY, |
||
| 881 | array( |
||
| 882 | RELOP => RELOP_EQ, |
||
| 883 | ULPROPTAG => PR_AB_PROVIDER_ID, |
||
| 884 | VALUE => array( |
||
| 885 | PR_AB_PROVIDER_ID => MUIDECSAB |
||
| 886 | ) |
||
| 887 | ) |
||
| 888 | ); |
||
| 889 | mapi_table_restrict($table, $restriction); |
||
| 890 | } |
||
| 891 | |||
| 892 | $items = mapi_table_queryallrows($table, array(PR_DISPLAY_NAME, PR_ENTRYID, PR_PARENT_ENTRYID, PR_DEPTH, PR_AB_PROVIDER_ID)); |
||
| 893 | |||
| 894 | $folders = array(); |
||
| 895 | |||
| 896 | $parent = false; |
||
| 897 | foreach($items as $item){ |
||
| 898 | // TODO: fix for missing PR_PARENT_ENTRYID, see #2190 |
||
| 899 | if ($item[PR_DEPTH]==0) |
||
| 900 | $parent = $item[PR_ENTRYID]; |
||
| 901 | |||
| 902 | $item[PR_PARENT_ENTRYID] = $parent; |
||
| 903 | |||
| 904 | $folders[] = array( |
||
| 905 | "props" => array( |
||
| 906 | "display_name" => $item[PR_DISPLAY_NAME] ?? '', |
||
| 907 | "entryid" => bin2hex($item[PR_ENTRYID]), |
||
| 908 | "parent_entryid"=> bin2hex($item[PR_PARENT_ENTRYID]), |
||
| 909 | "depth" => $item[PR_DEPTH], |
||
| 910 | "type" => $item[PR_AB_PROVIDER_ID] == MUIDECSAB ? "gab" : 'contacts', |
||
| 911 | "object_type" => MAPI_ABCONT |
||
| 912 | ) |
||
| 913 | ); |
||
| 914 | } |
||
| 915 | |||
| 916 | return $folders; |
||
| 917 | } |
||
| 918 | |||
| 919 | } |
||
| 920 | ?> |
||
|
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...
|
|||
| 921 |