grommunio /
grommunio-web
| 1 | <?php |
||
| 2 | /** |
||
| 3 | * Read Mail ItemModule |
||
| 4 | */ |
||
| 5 | class AddressbookItemModule extends ItemModule |
||
| 6 | { |
||
| 7 | |||
| 8 | /** |
||
| 9 | * Constructor |
||
| 10 | * @param int $id unique id. |
||
| 11 | * @param array $data list of all actions. |
||
| 12 | */ |
||
| 13 | function __construct($id, $data) |
||
| 14 | { |
||
| 15 | $this->userDetailProperties = $GLOBALS["properties"]->getAddressBookItemMailuserProperties(); |
||
| 16 | $this->abObjectDetailProperties = $GLOBALS["properties"]->getAddressBookItemABObjectProperties(); |
||
| 17 | $this->groupDetailProperties = $GLOBALS["properties"]->getAddressBookItemDistlistProperties(); |
||
| 18 | |||
| 19 | parent::__construct($id, $data); |
||
| 20 | } |
||
| 21 | |||
| 22 | /** |
||
| 23 | * Function which opens an item. |
||
| 24 | * @param object $store MAPI Message Store Object |
||
| 25 | * @param string $entryid entryid of the message |
||
| 26 | * @param array $action the action data, sent by the client |
||
| 27 | * @return boolean true on success or false on failure |
||
| 28 | */ |
||
| 29 | function open($store, $entryid, $action) |
||
| 30 | { |
||
| 31 | if($entryid) { |
||
| 32 | $data = array(); |
||
| 33 | |||
| 34 | try { |
||
| 35 | $abentry = mapi_ab_openentry($GLOBALS["mapisession"]->getAddressbook(false, true), $entryid); |
||
| 36 | } catch (MAPIException $e) { |
||
| 37 | // If the item not found in addressbook, it might be possible that |
||
| 38 | // this particular item was added by setup-contact-provider mechanism. |
||
| 39 | // Let us try to get that particular contact item in respective user store. |
||
| 40 | // @Fixme: After implementation of KC-350 this extra handling can be removed. |
||
| 41 | if ($e->getCode() == MAPI_E_NOT_FOUND || $e->getCode() == MAPI_E_INVALID_PARAMETER) { |
||
| 42 | $hexEntryid = bin2hex($entryid); |
||
| 43 | // Remove Address-Book-Provider prefix from the entryid |
||
| 44 | $externalEntryid = $GLOBALS["entryid"]->unwrapABEntryIdObj($hexEntryid); |
||
| 45 | // Check if it's a contact from the user's contacts folder |
||
| 46 | $contactItem = $GLOBALS['operations']->openMessage($GLOBALS['mapisession']->getDefaultMessageStore(), hex2bin($externalEntryid)); |
||
| 47 | |||
| 48 | if ($contactItem === false) { |
||
| 49 | // Retrieve user store entryid to which this external item belongs |
||
| 50 | $userStore = $GLOBALS['operations']->getOtherStoreFromEntryid($externalEntryid); |
||
| 51 | |||
| 52 | // If userStore not found it means user is not exists in address book |
||
| 53 | if($userStore === false) { |
||
| 54 | $msg = "The contact \"%s\" could not be displayed because it could not be retrieved or has been deleted"; |
||
| 55 | |||
| 56 | error_log(sprintf($msg, $action["message_action"]["username"])); |
||
| 57 | |||
| 58 | $e->setTitle(_('Contact not found')); |
||
| 59 | $e->setDisplayMessage(_("Contact information could not be displayed because the server had trouble retrieving the information.") . |
||
| 60 | _("Please contact your system administrator if the problem persists.")); |
||
| 61 | throw $e; |
||
| 62 | return false; |
||
| 63 | } |
||
| 64 | |||
| 65 | $e->setHandled(); |
||
| 66 | $contactItem = $GLOBALS['operations']->openMessage($userStore, hex2bin($externalEntryid)); |
||
| 67 | } |
||
| 68 | |||
| 69 | |||
| 70 | if ($contactItem != false) { |
||
| 71 | // Get necessary property from respective contact item |
||
| 72 | $contactItemProps = mapi_getprops($contactItem, Array(PR_GIVEN_NAME, PR_DISPLAY_NAME, PR_TITLE, PR_COMPANY_NAME)); |
||
| 73 | |||
| 74 | // Use the data retrieved from contact item to prepare response |
||
| 75 | // as similar as it seems like an addressbook item. |
||
| 76 | $data['props'] = array ( |
||
| 77 | 'object_type' => MAPI_MAILUSER, |
||
| 78 | 'given_name' => $contactItemProps[PR_GIVEN_NAME], |
||
| 79 | 'display_name' => $contactItemProps[PR_DISPLAY_NAME], |
||
| 80 | 'title' => $contactItemProps[PR_TITLE], |
||
| 81 | 'company_name' => $contactItemProps[PR_COMPANY_NAME] |
||
| 82 | ); |
||
| 83 | $data['entryid'] = $hexEntryid; |
||
| 84 | |||
| 85 | $this->addActionData("item", $data); |
||
| 86 | $GLOBALS["bus"]->addData($this->getResponseData()); |
||
| 87 | return; |
||
| 88 | } |
||
| 89 | } |
||
| 90 | } |
||
| 91 | |||
| 92 | if(mapi_last_hresult() == NOERROR && $abentry){ |
||
| 93 | $objecttypeprop = mapi_getprops($abentry, Array(PR_OBJECT_TYPE)); |
||
| 94 | |||
| 95 | if(isset($objecttypeprop[PR_OBJECT_TYPE])){ |
||
| 96 | // Get the properties for a MAILUSER object and process those MAILUSER specific props that require some more actions |
||
| 97 | if($objecttypeprop[PR_OBJECT_TYPE] == MAPI_MAILUSER){ |
||
| 98 | $messageprops = mapi_getprops($abentry, $this->userDetailProperties); |
||
| 99 | |||
| 100 | $props = Conversion::mapMAPI2XML($this->userDetailProperties, $messageprops); |
||
| 101 | |||
| 102 | if(isset($messageprops[PR_EMS_AB_THUMBNAIL_PHOTO])){ |
||
| 103 | $props['props']['ems_ab_thumbnail_photo'] = $GLOBALS['operations']->compressedImage($messageprops[PR_EMS_AB_THUMBNAIL_PHOTO]); |
||
| 104 | } |
||
| 105 | |||
| 106 | // Get the properties of the manager |
||
| 107 | $managerProps = $this->getManagerDetails($messageprops); |
||
| 108 | if($managerProps!==false){ |
||
|
0 ignored issues
–
show
introduced
by
Loading history...
|
|||
| 109 | $props['ems_ab_manager'] = array( |
||
| 110 | 'item' => $managerProps |
||
| 111 | ); |
||
| 112 | } |
||
| 113 | |||
| 114 | $homePhoneNumbers = $this->getHomePhoneNumbers($messageprops); |
||
| 115 | if (!empty($homePhoneNumbers)){ |
||
| 116 | // Add the list of home2_telephone_number_mv in the correct format to $props list to be send to the client |
||
| 117 | $props['home2_telephone_numbers'] = array( |
||
| 118 | 'item' => $homePhoneNumbers |
||
| 119 | ); |
||
| 120 | } |
||
| 121 | |||
| 122 | $businessPhoneNumbers = $this->getBusinessPhoneNumbers($messageprops); |
||
| 123 | if (!empty($businessPhoneNumbers)){ |
||
| 124 | // Add the list of business2_telephone_number_mv in the correct format to $props list to be send to the client |
||
| 125 | $props['business2_telephone_numbers'] = array( |
||
| 126 | 'item' => $businessPhoneNumbers |
||
| 127 | ); |
||
| 128 | } |
||
| 129 | |||
| 130 | // Get the properties of the "direct reports" |
||
| 131 | $directReportsList = $this->getDirectReportsDetails($messageprops); |
||
| 132 | if(!empty($directReportsList)){ |
||
| 133 | // Add the list of proxy_addresses in the correct format to the $props list to be send to the client. |
||
| 134 | $props['ems_ab_reports'] = array( |
||
| 135 | 'item' => $directReportsList |
||
| 136 | ); |
||
| 137 | } |
||
| 138 | |||
| 139 | // Get the properties for a DISTLIST object and process those DISTLIST specific props that require some more actions |
||
| 140 | } else { |
||
| 141 | $messageprops = mapi_getprops($abentry, $this->groupDetailProperties); |
||
| 142 | $props = Conversion::mapMAPI2XML($this->groupDetailProperties, $messageprops); |
||
| 143 | |||
| 144 | // Get the properties of the owner |
||
| 145 | $ownerProps = $this->getOwnerDetails($messageprops); |
||
| 146 | if($ownerProps!==false){ |
||
|
0 ignored issues
–
show
|
|||
| 147 | // We can use the same properties as we use for the manager in a MAILUSER |
||
| 148 | $props['ems_ab_owner'] = array( |
||
| 149 | 'item' => $ownerProps |
||
| 150 | ); |
||
| 151 | } |
||
| 152 | |||
| 153 | // Get the list of members for this DISTLSIT |
||
| 154 | $props['members'] = array( |
||
| 155 | 'item' => $this->getMembersDetails($abentry) |
||
| 156 | ); |
||
| 157 | } |
||
| 158 | |||
| 159 | // Get the proxy addresses list, this property exists in both MAILUSER and DISTLIST |
||
| 160 | $proxyAddresses = $this->getProxyAddressesDetails($messageprops); |
||
| 161 | // Remove the MV-flagged property |
||
| 162 | if(!empty($proxyAddresses)){ |
||
| 163 | // Add the list of proxy_addresses in the correct format to the $props list to be send to the client. |
||
| 164 | $props['ems_ab_proxy_addresses'] = array( |
||
| 165 | 'item' => $proxyAddresses |
||
| 166 | ); |
||
| 167 | } |
||
| 168 | |||
| 169 | // Get the properties of the group membership, this property exists in both MAILUSER and DISTLIST |
||
| 170 | $memberOfList = $this->getMemberOfDetails($messageprops); |
||
| 171 | if(!empty($memberOfList)){ |
||
| 172 | // Add the list of proxy_addresses in the correct format to the $props list to be send to the client. |
||
| 173 | $props['ems_ab_is_member_of_dl'] = array( |
||
| 174 | 'item' => $memberOfList |
||
| 175 | ); |
||
| 176 | } |
||
| 177 | |||
| 178 | // Remove the MV-flagged properties and also its single valued counterpart |
||
| 179 | unset($props['props']['ems_ab_is_member_of_dl']); |
||
| 180 | unset($props['props']['business2_telephone_number_mv']); |
||
| 181 | unset($props['props']['business2_telephone_number']); |
||
| 182 | unset($props['props']['home2_telephone_number_mv']); |
||
| 183 | unset($props['props']['home2_telephone_number']); |
||
| 184 | unset($props['props']['ems_ab_proxy_addresses_mv']); |
||
| 185 | unset($props['props']['ems_ab_proxy_addresses']); |
||
| 186 | unset($props['props']['ems_ab_reports_mv']); |
||
| 187 | unset($props['props']['ems_ab_reports']); |
||
| 188 | unset($props['props']['ems_ab_owner']); |
||
| 189 | unset($props['props']['ems_ab_manager']); |
||
| 190 | |||
| 191 | // Allowing to hook in and add more properties |
||
| 192 | $GLOBALS['PluginManager']->triggerHook("server.module.addressbookitemmodule.open.props", array( |
||
| 193 | 'moduleObject' =>& $this, |
||
| 194 | 'abentry' => $abentry, |
||
| 195 | 'object_type' => $objecttypeprop[PR_OBJECT_TYPE], |
||
| 196 | 'messageprops' => $messageprops, |
||
| 197 | 'props' =>& $props |
||
| 198 | )); |
||
| 199 | |||
| 200 | $data["item"] = $props; |
||
| 201 | $this->addActionData("item", $data); |
||
| 202 | } else { |
||
| 203 | // Handling error: not able to handle this type of object |
||
| 204 | $data["error"] = array(); |
||
| 205 | $data["error"]["message"] = _("Could not handle this type of object."); |
||
| 206 | $this->addActionData("error", $data); |
||
| 207 | } |
||
| 208 | } else { |
||
| 209 | // Handle not being able to open the object |
||
| 210 | $data["error"] = array(); |
||
| 211 | $data["error"]["hresult"] = mapi_last_hresult(); |
||
| 212 | $data["error"]["hresult_name"] = get_mapi_error_name(mapi_last_hresult()); |
||
| 213 | $data["error"]["message"] = _("Could not open this object."); |
||
| 214 | $this->addActionData("error", $data); |
||
| 215 | } |
||
| 216 | |||
| 217 | $GLOBALS["bus"]->addData($this->getResponseData()); |
||
| 218 | } |
||
| 219 | } |
||
| 220 | |||
| 221 | /** |
||
| 222 | * Get Business Telephone numbers in the messageprops array when it is set in the |
||
| 223 | * PR_HOME2_TELEPHONE_NUMBER_MV. This property is poorly documented and in Outlook it checks |
||
| 224 | * the property with and without the MV flag. The one without a MV flag can contain only one |
||
| 225 | * entry and the one with MV flag can contain a list. It then merges both into one list. |
||
| 226 | * This function has the same behavior and sets the list in the $messageprops. |
||
| 227 | * @param $messageprops Array Details properties of an user entry. |
||
| 228 | * @return Array List of telephone numbers |
||
| 229 | */ |
||
| 230 | function getHomePhoneNumbers($messageprops) |
||
| 231 | { |
||
| 232 | $list = Array(); |
||
| 233 | if (isset($messageprops[$this->userDetailProperties['home2_telephone_number']])){ |
||
| 234 | $list[] = $messageprops[$this->userDetailProperties['home2_telephone_number']]; |
||
| 235 | } |
||
| 236 | if(isset($messageprops[$this->userDetailProperties['home2_telephone_number_mv']])){ |
||
| 237 | $list = array_merge($list, $messageprops[$this->userDetailProperties['home2_telephone_number_mv']]); |
||
| 238 | } |
||
| 239 | |||
| 240 | $returnList = Array(); |
||
| 241 | for($i = 0, $len = count($list); $i < $len; $i++) { |
||
| 242 | array_push($returnList, Array('number' => $list[$i])); |
||
| 243 | } |
||
| 244 | return $returnList; |
||
| 245 | } |
||
| 246 | |||
| 247 | /** |
||
| 248 | * Get Business Telephone numbers in the messageprops array when it is set in the |
||
| 249 | * PR_BUSINESS2_TELEPHONE_NUMBER_MV. This property is poorly documented and in Outlook it checks |
||
| 250 | * the property with and without the MV flag. The one without a MV flag can contain only one |
||
| 251 | * entry and the one with MV flag can contain a list. It then merges both into one list. |
||
| 252 | * This function has the same behavior and sets the list in the $messageprops. |
||
| 253 | * @param $messageprops Array Details properties of an user entry. |
||
| 254 | * @return Array List of telephone numbers |
||
| 255 | */ |
||
| 256 | function getBusinessPhoneNumbers($messageprops) |
||
| 257 | { |
||
| 258 | $list = Array(); |
||
| 259 | if (isset($messageprops[$this->userDetailProperties['business2_telephone_number']])){ |
||
| 260 | $list[] = $messageprops[$this->userDetailProperties['business2_telephone_number']]; |
||
| 261 | } |
||
| 262 | if(isset($messageprops[$this->userDetailProperties['business2_telephone_number_mv']])){ |
||
| 263 | $list = array_merge($list, $messageprops[$this->userDetailProperties['business2_telephone_number_mv']]); |
||
| 264 | } |
||
| 265 | |||
| 266 | $returnList = Array(); |
||
| 267 | for($i = 0, $len = count($list); $i < $len; $i++) { |
||
| 268 | array_push($returnList, Array('number' => $list[$i])); |
||
| 269 | } |
||
| 270 | return $returnList; |
||
| 271 | } |
||
| 272 | |||
| 273 | /** |
||
| 274 | * Get Proxy Addresses in the messageprops array when it is set in the |
||
| 275 | * PR_EMS_AB_PROXY_ADDRESSES. This property is poorly documented and in Outlook it checks |
||
| 276 | * the property with and without the MV flag. The one without a MV flag can contain only one |
||
| 277 | * entry and the one with MV flag can contain a list. It then merges both into one list. |
||
| 278 | * This function has the same behavior and sets the list in the $messageprops. |
||
| 279 | * @param $messageprops Array Details properties of an user entry. |
||
| 280 | * @return Array List of addresses |
||
| 281 | */ |
||
| 282 | function getProxyAddressesDetails($messageprops) |
||
| 283 | { |
||
| 284 | $list = Array(); |
||
| 285 | if(isset($messageprops[$this->userDetailProperties['ems_ab_proxy_addresses']])){ |
||
| 286 | $list[] = $messageprops[$this->userDetailProperties['ems_ab_proxy_addresses']]; |
||
| 287 | } |
||
| 288 | if(isset($messageprops[$this->userDetailProperties['ems_ab_proxy_addresses_mv']])){ |
||
| 289 | $list = array_merge($list, $messageprops[$this->userDetailProperties['ems_ab_proxy_addresses_mv']]); |
||
| 290 | } |
||
| 291 | |||
| 292 | $returnList = Array(); |
||
| 293 | for($i = 0, $len = count($list); $i < $len; $i++) { |
||
| 294 | array_push($returnList, Array('address' => $list[$i])); |
||
| 295 | } |
||
| 296 | return $returnList; |
||
| 297 | } |
||
| 298 | |||
| 299 | /** |
||
| 300 | * Get the information of the manager from the GAB details of a MAPI_MAILUSER. Will use the |
||
| 301 | * entryid to get the properties. If no entryid if found false is returned. |
||
| 302 | * @param $messageprops Array Details properties of an user entry. |
||
| 303 | * @return Boolean|Array List of properties or false if no manager is set |
||
| 304 | */ |
||
| 305 | function getManagerDetails($messageprops) |
||
| 306 | { |
||
| 307 | if(isset($messageprops[$this->userDetailProperties['ems_ab_manager']])){ |
||
| 308 | $entryidMananager = $messageprops[$this->userDetailProperties['ems_ab_manager']]; |
||
| 309 | |||
| 310 | $managerEntry = mapi_ab_openentry($GLOBALS["mapisession"]->getAddressbook(), $entryidMananager); |
||
| 311 | $managerProps = mapi_getprops($managerEntry, $this->abObjectDetailProperties); |
||
| 312 | |||
| 313 | return Conversion::mapMAPI2XML($this->abObjectDetailProperties, $managerProps); |
||
| 314 | } |
||
| 315 | return false; |
||
| 316 | } |
||
| 317 | |||
| 318 | /** |
||
| 319 | * Get the list of users that have been set in the PR_EMS_AB_REPORTS property in the |
||
| 320 | * $messageprops array. This property is poorly documented and in Outlook it checks |
||
| 321 | * the property with and without the MV flag. The one without a MV flag can contain only one |
||
| 322 | * entry and the one with MV flag can contain a list. It then merges both into one list. |
||
| 323 | * This function has the same behavior and sets the list in the $messageprops. |
||
| 324 | * @param $messageprops Array Details properties of an user entry. |
||
| 325 | * @return Boolean|Array List of properties or false if no manager is set |
||
| 326 | */ |
||
| 327 | function getDirectReportsDetails($messageprops) |
||
| 328 | { |
||
| 329 | /* |
||
| 330 | * Get the entryIds from the PR_EMS_AB_REPORTS property (with and without MV flag as a |
||
| 331 | * fallback) and put the entryIds in a list. |
||
| 332 | */ |
||
| 333 | $entryids = Array(); |
||
| 334 | if(isset($messageprops[$this->userDetailProperties['ems_ab_reports']])){ |
||
| 335 | $entryids[] = $messageprops[$this->userDetailProperties['ems_ab_reports']]; |
||
| 336 | } |
||
| 337 | if(isset($messageprops[$this->userDetailProperties['ems_ab_reports_mv']])){ |
||
| 338 | $entryids = array_merge($entryids, $messageprops[$this->userDetailProperties['ems_ab_reports_mv']]); |
||
| 339 | } |
||
| 340 | |||
| 341 | $result = Array(); |
||
| 342 | // Convert the entryIds in an array of properties of the AB entryies |
||
| 343 | for($i = 0, $len = count($entryids); $i < $len; $i++){ |
||
| 344 | // Get the properties from the AB entry |
||
| 345 | $entry = mapi_ab_openentry($GLOBALS["mapisession"]->getAddressbook(), $entryids[$i]); |
||
| 346 | $props = mapi_getprops($entry, $this->abObjectDetailProperties); |
||
| 347 | // Convert the properties for each entry and put it in an array |
||
| 348 | $result[] = Conversion::mapMAPI2XML($this->abObjectDetailProperties, $props); |
||
| 349 | } |
||
| 350 | return $result; |
||
| 351 | } |
||
| 352 | |||
| 353 | /** |
||
| 354 | * Get the list of users that have been set in the PR_EMS_AB_MEMBER_OF_DL property in the |
||
| 355 | * $messageprops array. This property is poorly documented and in Outlook it checks |
||
| 356 | * the property with and without the MV flag. The one without a MV flag can contain only one |
||
| 357 | * entry and the one with MV flag can contain a list. It then merges both into one list. |
||
| 358 | * This function has the same behavior and sets the list in the $messageprops. |
||
| 359 | * @param $messageprops Array Details properties of an user entry. |
||
| 360 | * @return Boolean|Array List of properties or false if no manager is set |
||
| 361 | */ |
||
| 362 | function getMemberOfDetails($messageprops) |
||
| 363 | { |
||
| 364 | $result = Array(); |
||
| 365 | // Get the properties of the group membership |
||
| 366 | if(isset($messageprops[$this->userDetailProperties['ems_ab_is_member_of_dl']])){ |
||
| 367 | $entryids = $messageprops[$this->userDetailProperties['ems_ab_is_member_of_dl']]; |
||
| 368 | // Get the properties from every entryid in the memberOf list |
||
| 369 | for($i = 0, $len = count($entryids); $i < $len; $i++){ |
||
| 370 | // Get the properties from the AB entry |
||
| 371 | $entry = mapi_ab_openentry($GLOBALS["mapisession"]->getAddressbook(), $entryids[$i]); |
||
| 372 | $props = mapi_getprops($entry, $this->abObjectDetailProperties); |
||
| 373 | // Convert the properties for each entry and put it in an array |
||
| 374 | $result[] = Conversion::mapMAPI2XML($this->abObjectDetailProperties, $props); |
||
| 375 | } |
||
| 376 | } |
||
| 377 | return $result; |
||
| 378 | } |
||
| 379 | |||
| 380 | /** |
||
| 381 | * Get the information of the owner from the GAB details of a MAPI_DISTLIST. Will use the |
||
| 382 | * entryid to get the properties. If no entryid if found false is returned. |
||
| 383 | * @param $messageprops Array Details properties of an distlist entry. |
||
| 384 | * @return Boolean|Array List of properties or false if no owner is set |
||
| 385 | */ |
||
| 386 | function getOwnerDetails($messageprops) |
||
| 387 | { |
||
| 388 | if(isset($messageprops[$this->groupDetailProperties['ems_ab_owner']])){ |
||
| 389 | $entryidOwner = $messageprops[$this->groupDetailProperties['ems_ab_owner']]; |
||
| 390 | |||
| 391 | $ownerEntry = mapi_ab_openentry($GLOBALS["mapisession"]->getAddressbook(), $entryidOwner); |
||
| 392 | $ownerProps = mapi_getprops($ownerEntry, $this->abObjectDetailProperties); |
||
| 393 | |||
| 394 | return Conversion::mapMAPI2XML($this->abObjectDetailProperties, $ownerProps); |
||
| 395 | } |
||
| 396 | return false; |
||
| 397 | } |
||
| 398 | |||
| 399 | /** |
||
| 400 | * Get the information of the members from the GAB details of a MAPI_DISTLIST. The |
||
| 401 | * information can be found in the contentstable of the AB entry opened by the user. |
||
| 402 | * @param $abentry Resource Reference to the user-opened AB entry |
||
| 403 | * @return Boolean|Array List of members |
||
| 404 | */ |
||
| 405 | function getMembersDetails($abentry) |
||
| 406 | { |
||
| 407 | $result = Array(); |
||
| 408 | |||
| 409 | $table = mapi_folder_getcontentstable($abentry, MAPI_DEFERRED_ERRORS); |
||
| 410 | |||
| 411 | /* |
||
| 412 | * To prevent loading a huge list that the browser cannot handle, it is possible to |
||
| 413 | * limit the maximum number of shown items. Note that when the table doesn't |
||
| 414 | * contain the requested number of rows, it will not give any errors and simply |
||
| 415 | * return what is available. |
||
| 416 | * When the limit is 0 or below, then no limit is applied and we use 0x7fffffff |
||
| 417 | * to indicate we want to have all rows from the table. |
||
| 418 | */ |
||
| 419 | $rows = mapi_table_queryrows($table, $this->abObjectDetailProperties, 0, (ABITEMDETAILS_MAX_NUM_DISTLIST_MEMBERS > 0) ? ABITEMDETAILS_MAX_NUM_DISTLIST_MEMBERS : 0x7fffffff); |
||
| 420 | for($i = 0, $len = count($rows); $i < $len; $i++){ |
||
| 421 | $result[] = Conversion::mapMAPI2XML($this->abObjectDetailProperties, $rows[$i]); |
||
| 422 | } |
||
| 423 | |||
| 424 | return $result; |
||
| 425 | } |
||
| 426 | |||
| 427 | } |
||
| 428 | ?> |
||
|
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...
|
|||
| 429 |