grommunio /
grommunio-web
| 1 | <?php |
||
| 2 | /** |
||
| 3 | * RestoreItemsList Module |
||
| 4 | */ |
||
| 5 | class RestoreItemsListModule 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 | parent::__construct($id, $data); |
||
| 15 | |||
| 16 | $this->properties = $GLOBALS['properties']->getRestoreItemListProperties(); |
||
| 17 | |||
| 18 | } |
||
| 19 | |||
| 20 | /** |
||
| 21 | * Executes all the actions in the $data variable. |
||
| 22 | * @return boolean true on success of false on failure. |
||
| 23 | */ |
||
| 24 | function execute() |
||
| 25 | { |
||
| 26 | foreach($this->data as $actionType => $action) |
||
| 27 | { |
||
| 28 | if(isset($actionType)) { |
||
| 29 | try { |
||
| 30 | $store = $this->getActionStore($action); |
||
| 31 | $parententryid = $this->getActionParentEntryID($action); |
||
| 32 | $folderentryid = $this->getActionEntryID($action); |
||
| 33 | |||
| 34 | switch($actionType) { |
||
| 35 | case "list": |
||
| 36 | case "updatelist": |
||
| 37 | if (isset($action["message_action"], $action["message_action"]["action_type"])) { |
||
| 38 | $subActionType = $action["message_action"]["action_type"]; |
||
| 39 | switch ($subActionType) { |
||
| 40 | case "restoreAll": |
||
| 41 | $this->restoreAll($store, $folderentryid, $action); |
||
| 42 | break; |
||
| 43 | case "deleteAll": |
||
| 44 | $this->deleteAll($store, $folderentryid, $action); |
||
| 45 | break; |
||
| 46 | } |
||
| 47 | } else { |
||
| 48 | $this->itemList($store, $folderentryid, $action); |
||
| 49 | } |
||
| 50 | break; |
||
| 51 | case "delete": |
||
| 52 | $itemType = $action["message_action"]["action_type"]; |
||
| 53 | |||
| 54 | switch($itemType) { |
||
| 55 | case "restorefolder" : |
||
| 56 | $this->restoreFolder($store, $parententryid, $folderentryid); |
||
| 57 | break; |
||
| 58 | |||
| 59 | case "deletefolder" : |
||
| 60 | $this->deleteFolder($store, $parententryid, $action); |
||
| 61 | break; |
||
| 62 | |||
| 63 | case "restoremessage" : |
||
| 64 | $this->restoreItems($store, $parententryid, $action); |
||
| 65 | break; |
||
| 66 | |||
| 67 | case "deletemessage" : |
||
| 68 | $this->deleteItems($store, $parententryid, $action); |
||
| 69 | break; |
||
| 70 | |||
| 71 | default: |
||
| 72 | $this->handleUnknownActionType($itemType); |
||
| 73 | } |
||
| 74 | break; |
||
| 75 | |||
| 76 | default: |
||
| 77 | $this->handleUnknownActionType($actionType); |
||
| 78 | } |
||
| 79 | } catch (MAPIException $e) { |
||
| 80 | $this->processException($e, $actionType); |
||
| 81 | } |
||
| 82 | } |
||
| 83 | } |
||
| 84 | } |
||
| 85 | |||
| 86 | /** |
||
| 87 | * Function which permanently delete all folder or message items. |
||
| 88 | * |
||
| 89 | * @param {object} $store store object |
||
| 90 | * @param {binary} $folderentryid entry id of that particular folder. |
||
| 91 | * @param object $action request data. |
||
| 92 | */ |
||
| 93 | function deleteAll($store, $folderentryid, $action) |
||
| 94 | { |
||
| 95 | $folder = mapi_msgstore_openentry($store, $folderentryid); |
||
| 96 | |||
| 97 | // delete all folders. |
||
| 98 | if (isset($action["itemType"]) && $action["itemType"] == "folder") { |
||
| 99 | $table = mapi_folder_gethierarchytable($folder, MAPI_DEFERRED_ERRORS | SHOW_SOFT_DELETES); |
||
| 100 | $items = mapi_table_queryallrows($table, array(PR_ENTRYID)); |
||
| 101 | $restoreItems = array(); |
||
| 102 | foreach ($items as $item) { |
||
| 103 | array_push($restoreItems, $item[PR_ENTRYID]); |
||
| 104 | } |
||
| 105 | |||
| 106 | foreach ($restoreItems as $restoreItem) { |
||
| 107 | mapi_folder_deletefolder($folder, $restoreItem, DEL_FOLDERS | DEL_MESSAGES | DELETE_HARD_DELETE); |
||
| 108 | } |
||
| 109 | } else { |
||
| 110 | // delete all messages |
||
| 111 | $table = mapi_folder_getcontentstable($folder, MAPI_DEFERRED_ERRORS | SHOW_SOFT_DELETES); |
||
| 112 | $items = mapi_table_queryallrows($table, array(PR_ENTRYID)); |
||
| 113 | |||
| 114 | $restoreItems = array(); |
||
| 115 | foreach ($items as $item) { |
||
| 116 | array_push($restoreItems, $item[PR_ENTRYID]); |
||
| 117 | } |
||
| 118 | |||
| 119 | mapi_folder_deletemessages($folder, $restoreItems , DELETE_HARD_DELETE); |
||
| 120 | } |
||
| 121 | |||
| 122 | $this->addActionData("list", array("item" => array())); |
||
| 123 | $GLOBALS["bus"]->addData($this->getResponseData()); |
||
| 124 | } |
||
| 125 | |||
| 126 | /** |
||
| 127 | * Function used to restore all folders. |
||
| 128 | * |
||
| 129 | * @param {object} $store store object. |
||
| 130 | * @param {object} $folder folder data which needs to restore. |
||
| 131 | * @throws MAPIException |
||
| 132 | */ |
||
| 133 | function restoreAllFolders($store, $folder) |
||
| 134 | { |
||
| 135 | $table = mapi_folder_gethierarchytable($folder, MAPI_DEFERRED_ERRORS | SHOW_SOFT_DELETES); |
||
| 136 | $items = mapi_table_queryallrows($table, array(PR_ENTRYID)); |
||
| 137 | $restoreItems = array(); |
||
| 138 | foreach ($items as $item) { |
||
| 139 | array_push($restoreItems, $item[PR_ENTRYID]); |
||
| 140 | } |
||
| 141 | |||
| 142 | foreach ($restoreItems as $restoreItem) { |
||
| 143 | try { |
||
| 144 | /* |
||
| 145 | * we should first try to copy folder and if it returns MAPI_E_COLLISION then |
||
| 146 | * only we should check for the conflicting folder names and generate a new name |
||
| 147 | * and restore folder with the generated name. |
||
| 148 | */ |
||
| 149 | mapi_folder_copyfolder($folder, $restoreItem, $folder, null, FOLDER_MOVE); |
||
| 150 | } catch (MAPIException $e) { |
||
| 151 | if($e->getCode() == MAPI_E_COLLISION) { |
||
| 152 | $folder = mapi_msgstore_openentry($store, $restoreItem, SHOW_SOFT_DELETES); |
||
| 153 | $folderNameProps = mapi_getprops($folder, array(PR_DISPLAY_NAME)); |
||
| 154 | $foldername = $GLOBALS["operations"]->checkFolderNameConflict($store, $folder, $folderNameProps[PR_DISPLAY_NAME]); |
||
| 155 | mapi_folder_copyfolder($folder, $restoreItem, $folder, $foldername, FOLDER_MOVE); |
||
| 156 | } else { |
||
| 157 | // all other errors should be propagated to higher level exception handlers |
||
| 158 | throw $e; |
||
| 159 | } |
||
| 160 | } |
||
| 161 | } |
||
| 162 | |||
| 163 | // Notify the parent folder. |
||
| 164 | $this->notifyParentFolder($store, $folder, $folder); |
||
| 165 | } |
||
| 166 | |||
| 167 | /** |
||
| 168 | * Function which used to restore and message for give folder. |
||
| 169 | * |
||
| 170 | * @param {object} $folder the content of this folder is going to restored. |
||
| 171 | */ |
||
| 172 | function restoreAllItems($folder) |
||
| 173 | { |
||
| 174 | $table = mapi_folder_getcontentstable($folder, MAPI_DEFERRED_ERRORS | SHOW_SOFT_DELETES); |
||
| 175 | $items = mapi_table_queryallrows($table, array(PR_ENTRYID)); |
||
| 176 | |||
| 177 | $restoreItems = array(); |
||
| 178 | foreach ($items as $item) { |
||
| 179 | array_push($restoreItems, $item[PR_ENTRYID]); |
||
| 180 | } |
||
| 181 | |||
| 182 | mapi_folder_copymessages($folder, $restoreItems, $folder, MESSAGE_MOVE); |
||
| 183 | |||
| 184 | // as after moving the message/s the entryid gets changed, so need to notify about the folder |
||
| 185 | // so that we can update the folder on parent page. |
||
| 186 | $folderProps = mapi_getprops($folder, array(PR_STORE_ENTRYID, PR_ENTRYID)); |
||
| 187 | |||
| 188 | /* when we restore any message from soft deleted system then we are actually copying the item, so at that time entryid of |
||
| 189 | * that particular item gets changed, so to notify client about changes we need to |
||
| 190 | * notify parent folder where we have restored the message |
||
| 191 | */ |
||
| 192 | $props[PR_PARENT_ENTRYID] = $folderProps[PR_ENTRYID]; |
||
| 193 | $props[PR_STORE_ENTRYID] = $folderProps[PR_STORE_ENTRYID]; |
||
| 194 | |||
| 195 | $GLOBALS["bus"]->notify(bin2hex($folderProps[PR_ENTRYID]), TABLE_SAVE, $props); |
||
| 196 | } |
||
| 197 | |||
| 198 | /** |
||
| 199 | * Function restored restore all folder or message based on give itemType. |
||
| 200 | * |
||
| 201 | * @param {object} $store store object |
||
| 202 | * @param {binary} $folderentryid entry id of that particular folder. |
||
| 203 | * @param object $action request data. |
||
| 204 | * @throws MAPIException |
||
| 205 | */ |
||
| 206 | function restoreAll($store, $folderentryid, $action) |
||
| 207 | { |
||
| 208 | $folder = mapi_msgstore_openentry($store, $folderentryid); |
||
| 209 | |||
| 210 | if (isset($action["itemType"]) && $action["itemType"] == "folder") { |
||
| 211 | try { |
||
| 212 | $this->restoreAllFolders($store, $folder); |
||
| 213 | } catch (MAPIException $e) { |
||
| 214 | throw $e; |
||
| 215 | } |
||
| 216 | } else { |
||
| 217 | $this->restoreAllItems($folder); |
||
| 218 | } |
||
| 219 | |||
| 220 | $this->addActionData("list", array("item" => array())); |
||
| 221 | $GLOBALS["bus"]->addData($this->getResponseData()); |
||
| 222 | } |
||
| 223 | |||
| 224 | /** |
||
| 225 | * Function to retrieve the list of messages or folder of particular folder |
||
| 226 | * @param object $store store object. |
||
| 227 | * @param binary $entryid entry id of that particular folder. |
||
| 228 | * @param object $action request data. |
||
| 229 | */ |
||
| 230 | function itemList($store, $entryid, $action) |
||
| 231 | { |
||
| 232 | // Restriction |
||
| 233 | $this->parseRestriction($action); |
||
| 234 | |||
| 235 | //set the this->$sort variable. |
||
| 236 | $this->parseSortOrder($action); |
||
| 237 | |||
| 238 | if(isset($action['restriction']['limit'])){ |
||
| 239 | $limit = $action['restriction']['limit']; |
||
| 240 | } else { |
||
| 241 | $limit = $GLOBALS['settings']->get('zarafa/v1/main/page_size', 50); |
||
| 242 | } |
||
| 243 | |||
| 244 | $folder = mapi_msgstore_openentry($store, $entryid); |
||
| 245 | |||
| 246 | if (isset($action["itemType"]) && $action["itemType"] == "folder") { |
||
| 247 | $table = mapi_folder_gethierarchytable($folder, MAPI_DEFERRED_ERRORS | SHOW_SOFT_DELETES); |
||
| 248 | } else { |
||
| 249 | $table = mapi_folder_getcontentstable($folder, MAPI_DEFERRED_ERRORS | SHOW_SOFT_DELETES); |
||
| 250 | } |
||
| 251 | |||
| 252 | $data = $GLOBALS["operations"]->getTableContent($table, $this->properties, $this->sort, $this->start, $limit, $this->restriction); |
||
| 253 | |||
| 254 | $this->addActionData("list", $data); |
||
| 255 | $GLOBALS["bus"]->addData($this->getResponseData()); |
||
| 256 | } |
||
| 257 | |||
| 258 | /** |
||
| 259 | * Function to delete selected items of particular folder |
||
| 260 | * @param object $store store object. |
||
| 261 | * @param binary $parententryid entry id of the folder which contain particular item to be deleted. |
||
| 262 | * @param object $items request data. |
||
| 263 | */ |
||
| 264 | function deleteItems($store, $parententryid, $items){ |
||
| 265 | |||
| 266 | if(is_assoc_array($items)) { |
||
| 267 | // wrap single item in an array |
||
| 268 | $items = array($items); |
||
| 269 | } |
||
| 270 | |||
| 271 | $sfolder = mapi_msgstore_openentry($store, $parententryid); |
||
| 272 | |||
| 273 | for($index = 0, $len = count($items); $index < $len; $index++) { |
||
| 274 | mapi_folder_deletemessages($sfolder, array(hex2bin($items[$index]['entryid'])), DELETE_HARD_DELETE); |
||
| 275 | } |
||
| 276 | $this->sendFeedback(true); |
||
| 277 | } |
||
| 278 | |||
| 279 | /** |
||
| 280 | * Function to restore message present into the selected folder |
||
| 281 | * @param object $store store object. |
||
| 282 | * @param binary $parententryid entry id of the folder which contain particular item to be restored. |
||
| 283 | * @param object $items request data. |
||
| 284 | */ |
||
| 285 | function restoreItems($store, $parententryid, $items){ |
||
| 286 | |||
| 287 | if(is_assoc_array($items)) { |
||
| 288 | // wrap single item in an array |
||
| 289 | $items = array($items); |
||
| 290 | } |
||
| 291 | |||
| 292 | $sfolder = mapi_msgstore_openentry($store, $parententryid); |
||
| 293 | |||
| 294 | for($index = 0, $len = count($items); $index < $len; $index++) { |
||
| 295 | mapi_folder_copymessages($sfolder, array(hex2bin($items[$index]['entryid'])), $sfolder, MESSAGE_MOVE); |
||
| 296 | } |
||
| 297 | |||
| 298 | // as after moving the message/s the entryid gets changed, so need to notify about the folder |
||
| 299 | // so that we can update the folder on parent page. |
||
| 300 | $folderProps = mapi_getprops($sfolder, array(PR_STORE_ENTRYID, PR_ENTRYID)); |
||
| 301 | |||
| 302 | /* when we restore any message from soft deleted system then we are actually copying the item, so at that time entryid of |
||
| 303 | * that particular item gets changed, so to notify client about changes we need to |
||
| 304 | * notify parent folder where we have restored the message |
||
| 305 | */ |
||
| 306 | $props[PR_PARENT_ENTRYID] = $folderProps[PR_ENTRYID]; |
||
| 307 | $props[PR_STORE_ENTRYID] = $folderProps[PR_STORE_ENTRYID]; |
||
| 308 | $GLOBALS["bus"]->notify(bin2hex($folderProps[PR_ENTRYID]), TABLE_SAVE, $props); |
||
| 309 | $this->sendFeedback(true); |
||
| 310 | } |
||
| 311 | |||
| 312 | /** |
||
| 313 | * Function to delete selected folders |
||
| 314 | * @param object $store store object. |
||
| 315 | * @param binary $parententryid entry id of the folder which contain particular folder to be deleted. |
||
| 316 | * @param object $folders request data. |
||
| 317 | */ |
||
| 318 | function deleteFolder($store, $parententryid, $folders){ |
||
| 319 | |||
| 320 | if(is_assoc_array($folders)) { |
||
| 321 | // wrap single folder in an array |
||
| 322 | $folders = array($folders); |
||
| 323 | } |
||
| 324 | |||
| 325 | $sfolder = mapi_msgstore_openentry($store, $parententryid); |
||
| 326 | |||
| 327 | for($index = 0, $len = count($folders); $index < $len; $index++) { |
||
| 328 | mapi_folder_deletefolder($sfolder, hex2bin($folders[$index]['entryid']), DEL_FOLDERS | DEL_MESSAGES | DELETE_HARD_DELETE); |
||
| 329 | } |
||
| 330 | |||
| 331 | $this->sendFeedback(true); |
||
| 332 | } |
||
| 333 | |||
| 334 | /** |
||
| 335 | * Function to restore soft deleted folder of particular folder |
||
| 336 | * @param object $store store object. |
||
| 337 | * @param binary $parententryid entry id of the folder which contain particular folder to be restored. |
||
| 338 | * @param binary $folderentryid entry id of the folder to be restored. |
||
| 339 | */ |
||
| 340 | function restoreFolder($store, $parententryid, $folderentryid) |
||
| 341 | { |
||
| 342 | $sfolder = mapi_msgstore_openentry($store, $parententryid); |
||
| 343 | try { |
||
| 344 | /* |
||
| 345 | * we should first try to copy folder and if it returns MAPI_E_COLLISION then |
||
| 346 | * only we should check for the conflicting folder names and generate a new name |
||
| 347 | * and restore folder with the generated name. |
||
| 348 | */ |
||
| 349 | mapi_folder_copyfolder($sfolder, $folderentryid, $sfolder, null, FOLDER_MOVE); |
||
| 350 | } catch (MAPIException $e) { |
||
| 351 | if($e->getCode() == MAPI_E_COLLISION) { |
||
| 352 | $folder = mapi_msgstore_openentry($store, $folderentryid, SHOW_SOFT_DELETES); |
||
| 353 | $folderNameProps = mapi_getprops($folder, array(PR_DISPLAY_NAME)); |
||
| 354 | $foldername = $GLOBALS["operations"]->checkFolderNameConflict($store, $sfolder, $folderNameProps[PR_DISPLAY_NAME]); |
||
| 355 | mapi_folder_copyfolder($sfolder, $folderentryid, $sfolder, $foldername, FOLDER_MOVE); |
||
| 356 | } else { |
||
| 357 | // all other errors should be propagated to higher level exception handlers |
||
| 358 | throw $e; |
||
| 359 | } |
||
| 360 | } |
||
| 361 | |||
| 362 | // notify the parent folder |
||
| 363 | $parentFolder = mapi_msgstore_openentry($store, $parententryid); |
||
| 364 | $this->notifyParentFolder($store,$sfolder, $parentFolder); |
||
| 365 | $this->sendFeedback(true); |
||
| 366 | } |
||
| 367 | |||
| 368 | /** |
||
| 369 | * Notify the parent folder about restoration. |
||
| 370 | * |
||
| 371 | * @param object $store store object. |
||
| 372 | * @param object $folder mapi folder which contain particular folder to be restored. |
||
| 373 | * @param object $parentFolder mapi folder which is going to notify. |
||
| 374 | */ |
||
| 375 | function notifyParentFolder($store, $folder, $parentFolder) |
||
| 376 | { |
||
| 377 | /* when we restore any folder from soft deleted system then we are actually copying the folder, so at that time entryid of |
||
| 378 | * folder gets changed and we don't have notification system to get new entryid, so to notify client about changes we need to |
||
| 379 | * notify all subfolders of parent folder where we have restored the folder |
||
| 380 | */ |
||
| 381 | $hierarchyTable = mapi_folder_gethierarchytable($folder, CONVENIENT_DEPTH | MAPI_DEFERRED_ERRORS); |
||
| 382 | mapi_table_sort($hierarchyTable, array(PR_DISPLAY_NAME => TABLE_SORT_ASCEND), TBL_BATCH); |
||
| 383 | |||
| 384 | $subfolders = mapi_table_queryallrows($hierarchyTable, array(PR_ENTRYID)); |
||
| 385 | |||
| 386 | if (is_array($subfolders)) { |
||
| 387 | foreach($subfolders as $subfolder) { |
||
| 388 | $folderObject = mapi_msgstore_openentry($store, $subfolder[PR_ENTRYID]); |
||
| 389 | $folderProps = mapi_getprops($folderObject, array(PR_ENTRYID, PR_STORE_ENTRYID)); |
||
| 390 | $GLOBALS["bus"]->notify(bin2hex($subfolder[PR_ENTRYID]), OBJECT_SAVE, $folderProps); |
||
| 391 | } |
||
| 392 | } |
||
| 393 | |||
| 394 | $folderProps = mapi_getprops($parentFolder, array(PR_ENTRYID, PR_STORE_ENTRYID)); |
||
| 395 | $GLOBALS["bus"]->notify(bin2hex($folderProps[PR_ENTRYID]), OBJECT_SAVE, $folderProps); |
||
| 396 | } |
||
| 397 | } |
||
| 398 | ?> |
||
|
0 ignored issues
–
show
|
|||
| 399 |
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.