grommunio /
grommunio-web
| 1 | <?php |
||
| 2 | include_once(__DIR__ . '/../mapi/class.taskrecurrence.php'); |
||
| 3 | include_once(__DIR__ . '/../mapi/class.taskrequest.php'); |
||
| 4 | |||
| 5 | /** |
||
| 6 | * Task ItemModule |
||
| 7 | * Module which openes, creates, saves and deletes an item. It |
||
| 8 | * extends the Module class. |
||
| 9 | */ |
||
| 10 | class TaskItemModule extends ItemModule |
||
| 11 | { |
||
| 12 | /** |
||
| 13 | * Constructor |
||
| 14 | * @param int $id unique id. |
||
| 15 | * @param array $data list of all actions. |
||
| 16 | */ |
||
| 17 | function __construct($id, $data) |
||
| 18 | { |
||
| 19 | parent::__construct($id, $data); |
||
| 20 | |||
| 21 | $this->properties = $GLOBALS["properties"]->getTaskProperties(); |
||
| 22 | |||
| 23 | $this->plaintext = true; |
||
| 24 | } |
||
| 25 | |||
| 26 | function open($store, $entryid, $action) |
||
| 27 | { |
||
| 28 | $data = array(); |
||
| 29 | |||
| 30 | $message = $GLOBALS['operations']->openMessage($store, $entryid); |
||
| 31 | |||
| 32 | if(empty($message)) { |
||
| 33 | return; |
||
| 34 | } |
||
| 35 | |||
| 36 | // Open embedded message if requested |
||
| 37 | $attachNum = !empty($action['attach_num']) ? $action['attach_num'] : false; |
||
| 38 | if($attachNum) { |
||
| 39 | // get message props of sub message |
||
| 40 | $parentMessage = $message; |
||
| 41 | $message = $GLOBALS['operations']->openMessage($store, $entryid, $attachNum); |
||
| 42 | |||
| 43 | if(empty($message)) { |
||
| 44 | return; |
||
| 45 | } |
||
| 46 | |||
| 47 | $data['item'] = $GLOBALS['operations']->getEmbeddedMessageProps($store, $message, $this->properties, $parentMessage, $attachNum); |
||
| 48 | } else { |
||
| 49 | $data['item'] = $GLOBALS['operations']->getMessageProps($store, $message, $this->properties, $this->plaintext); |
||
| 50 | |||
| 51 | $tr = new TaskRequest($store, $message, $GLOBALS['mapisession']->getSession()); |
||
| 52 | if ($tr->isTaskRequest() || $tr->isTaskRequestResponse()) { |
||
| 53 | $tr->isTaskRequest() ? $tr->processTaskRequest() : $tr->processTaskResponse(); |
||
| 54 | $task = $tr->getAssociatedTask(false); |
||
| 55 | $action["message_action"]["open_task"] = true; |
||
| 56 | $data = $this->getMessageProps($store, $entryid, $action, $task); |
||
| 57 | $data['item']['props']['task_not_found'] = ($task === false); |
||
| 58 | } |
||
| 59 | } |
||
| 60 | |||
| 61 | $this->addActionData('item', $data); |
||
| 62 | $GLOBALS['bus']->addData($this->getResponseData()); |
||
| 63 | } |
||
| 64 | |||
| 65 | /** |
||
| 66 | * Function which used to open and get the all properties of the message. if message_action |
||
| 67 | * "open_task" is true then it will open the associated task of task request and return its data item |
||
| 68 | * else return the task request data item. |
||
| 69 | * |
||
| 70 | * @param object $store MAPI Message Store Object |
||
| 71 | * @param string $entryid entryid of the message |
||
| 72 | * @param object $task associated task of task request |
||
| 73 | * |
||
| 74 | * @return array $data item properties of given message. |
||
| 75 | */ |
||
| 76 | function getMessageProps($store, $entryid, $action, $task) |
||
| 77 | { |
||
| 78 | if(isset($action["message_action"]["open_task"]) && $action["message_action"]["open_task"] && $task !== false) { |
||
| 79 | $taskProps = mapi_getprops($task, array(PR_ENTRYID, PR_PARENT_ENTRYID,PR_STORE_ENTRYID)); |
||
| 80 | $message = $GLOBALS['operations']->openMessage($store, $taskProps[PR_ENTRYID]); |
||
| 81 | } else { |
||
| 82 | $message = $GLOBALS['operations']->openMessage($store, $entryid); |
||
| 83 | } |
||
| 84 | $data['item'] = $GLOBALS['operations']->getMessageProps($store, $message, $this->properties, $this->plaintext); |
||
| 85 | return $data; |
||
| 86 | } |
||
| 87 | |||
| 88 | /** |
||
| 89 | * Function which saves an item. |
||
| 90 | * @param object $store MAPI Message Store Object |
||
| 91 | * @param string $parententryid parent entryid of the message |
||
| 92 | * @param array $action the action data, sent by the client |
||
| 93 | * @return boolean true on success or false on failure |
||
| 94 | */ |
||
| 95 | function save($store, $parententryid, $entryid, $action) |
||
| 96 | { |
||
| 97 | if(isset($action["props"])) { |
||
| 98 | if(!$store && !$parententryid) { |
||
| 99 | if(isset($action["props"]["message_class"])) { |
||
| 100 | $store = $GLOBALS["mapisession"]->getDefaultMessageStore(); |
||
| 101 | $parententryid = $this->getDefaultFolderEntryID($store, $action["props"]["message_class"]); |
||
| 102 | } |
||
| 103 | } |
||
| 104 | |||
| 105 | if ($store && $parententryid) { |
||
| 106 | // Set the message flag for the item |
||
| 107 | if(isset($action['props']['message_flags']) && $entryid) { |
||
| 108 | $GLOBALS['operations']->setMessageFlag($store, $entryid, $action['props']['message_flags']); |
||
| 109 | } |
||
| 110 | |||
| 111 | $messageProps = $this->saveTask($store, $parententryid, $entryid, $action); |
||
| 112 | |||
| 113 | if($messageProps) { |
||
| 114 | $send = isset($action["message_action"]["send"]) ? $action["message_action"]["send"] : false; |
||
| 115 | $message = $GLOBALS['operations']->openMessage($store, $messageProps[PR_ENTRYID]); |
||
| 116 | $data = $GLOBALS['operations']->getMessageProps($store, $message, $this->properties, $this->plaintext); |
||
| 117 | |||
| 118 | // taskupdates property true if assigner as checked "Keep copy of task in task list" checkbox. |
||
| 119 | // if it is not checked then it means user don't want assigned task copy in his task list. |
||
| 120 | if($send && isset($data["props"]['taskupdates']) && $data["props"]['taskupdates'] === false) { |
||
| 121 | // Hard delete the task if taskupdates property is not true. |
||
| 122 | $folder = mapi_msgstore_openentry($store, $parententryid); |
||
| 123 | mapi_folder_deletemessages($folder, array($messageProps[PR_ENTRYID]), DELETE_HARD_DELETE); |
||
| 124 | |||
| 125 | $data = Conversion::mapMAPI2XML($this->properties , $messageProps); |
||
| 126 | $GLOBALS["bus"]->notify(bin2hex($parententryid), TABLE_DELETE, $messageProps); |
||
| 127 | } else { |
||
| 128 | $GLOBALS["bus"]->notify(bin2hex($parententryid), TABLE_SAVE, $messageProps); |
||
| 129 | } |
||
| 130 | // Notify To-Do list folder as new task item was created. |
||
| 131 | $GLOBALS["bus"]->notify(bin2hex(TodoList::getEntryId()), OBJECT_SAVE, $messageProps); |
||
| 132 | $this->addActionData("update", array("item" => $data)); |
||
| 133 | $GLOBALS["bus"]->addData($this->getResponseData()); |
||
| 134 | } |
||
| 135 | } |
||
| 136 | } |
||
| 137 | } |
||
| 138 | |||
| 139 | /** |
||
| 140 | * Function which deletes an item. |
||
| 141 | * @param object $store MAPI Message Store Object |
||
| 142 | * @param string $parententryid parent entryid of the message |
||
| 143 | * @param string $entryid entryid of the message |
||
| 144 | * @param array $action the action data, sent by the client |
||
| 145 | * @return boolean true on success or false on failure |
||
| 146 | */ |
||
| 147 | function delete($store, $parententryid, $entryids, $action) |
||
| 148 | { |
||
| 149 | if($store && $parententryid) { |
||
| 150 | $props = array(); |
||
| 151 | $props[PR_PARENT_ENTRYID] = $parententryid; |
||
| 152 | $props[PR_ENTRYID] = $entryids; |
||
| 153 | |||
| 154 | $storeprops = mapi_getprops($store, array(PR_ENTRYID)); |
||
| 155 | $props[PR_STORE_ENTRYID] = $storeprops[PR_ENTRYID]; |
||
| 156 | |||
| 157 | $result = $this->deleteTask($store, $parententryid, $entryids, $action); |
||
| 158 | |||
| 159 | if ($result) { |
||
| 160 | if (isset($result['occurrenceDeleted']) && $result['occurrenceDeleted']) { |
||
| 161 | // Occurrence deleted, update item |
||
| 162 | $GLOBALS["bus"]->notify(bin2hex($parententryid), TABLE_SAVE, $props); |
||
| 163 | } else { |
||
| 164 | $GLOBALS["bus"]->notify(bin2hex($parententryid), TABLE_DELETE, $props); |
||
| 165 | } |
||
| 166 | $this->sendFeedback(true); |
||
| 167 | } |
||
| 168 | } |
||
| 169 | } |
||
| 170 | |||
| 171 | /** |
||
| 172 | * Deletes a task. |
||
| 173 | * |
||
| 174 | * deletes occurrence if task is a recurring item. |
||
| 175 | * @param mapistore $store MAPI Message Store Object |
||
| 176 | * @param string $parententryid parent entryid of the messages to be deleted |
||
| 177 | * @param array $entryids a list of entryids which will be deleted |
||
| 178 | * @param boolean $softDelete flag for soft-deleting (when user presses Shift+Del) |
||
| 179 | * @return boolean true if action succeeded, false if not |
||
| 180 | */ |
||
| 181 | function deleteTask($store, $parententryid, $entryids, $action) |
||
| 182 | { |
||
| 183 | $result = false; |
||
| 184 | $message = mapi_msgstore_openentry($store, $entryids); |
||
| 185 | $messageAction = isset($action["message_action"]["action_type"]) ? $action["message_action"]["action_type"] : false; |
||
| 186 | // If user wants to delete only occurrence then delete this occurrence |
||
| 187 | if (!is_array($entryids) && $messageAction) { |
||
| 188 | if ($message) { |
||
| 189 | if ($messageAction == 'occurrence') { |
||
| 190 | $recur = new TaskRecurrence($store, $message); |
||
| 191 | $occurrenceDeleted = $recur->deleteOccurrence($action); |
||
| 192 | } else if ($messageAction == 'declineAndDelete' || $messageAction == 'completeAndDelete') { |
||
| 193 | $taskReq = new TaskRequest($store, $message, $GLOBALS["mapisession"]->getSession()); |
||
| 194 | if ($messageAction == 'declineAndDelete') { |
||
| 195 | $taskReq->doDecline(); |
||
| 196 | } else if ($messageAction == 'completeAndDelete') { |
||
| 197 | $taskReq->sendCompleteUpdate(); |
||
| 198 | } |
||
| 199 | } |
||
| 200 | } |
||
| 201 | } |
||
| 202 | |||
| 203 | // Deleting occurrence failed, maybe that was its last occurrence, so now we delete whole series. |
||
| 204 | if (!isset($occurrenceDeleted) || !$occurrenceDeleted) { |
||
| 205 | $properties = $GLOBALS["properties"]->getTaskProperties(); |
||
| 206 | $goid = mapi_getprops($message, array($properties["task_goid"])); |
||
| 207 | // If task is assigned task to assignee and user is trying to delete the task. |
||
| 208 | // then we have to remove respective task request(IPM.TaskRequest.Accept/Decline/Update) |
||
| 209 | // notification mail from inbox. |
||
| 210 | if(isset($goid[$properties["task_goid"]]) && !empty($goid[$properties["task_goid"]])) { |
||
| 211 | $taskReq = new TaskRequest($store, $message, $GLOBALS["mapisession"]->getSession()); |
||
| 212 | $result = $taskReq->deleteReceivedTR(); |
||
| 213 | if($result) { |
||
| 214 | $GLOBALS["bus"]->notify(bin2hex($result[PR_PARENT_ENTRYID]), TABLE_DELETE, $result); |
||
| 215 | } |
||
| 216 | } |
||
| 217 | |||
| 218 | // If softdelete is set then set it in softDelete variable and pass it for deleting message. |
||
| 219 | $softDelete = isset($action['message_action']['soft_delete']) ? $action['message_action']['soft_delete'] : false; |
||
| 220 | $result = $GLOBALS["operations"]->deleteMessages($store, $parententryid, $entryids, $softDelete); |
||
| 221 | } else { |
||
| 222 | $result = array('occurrenceDeleted' => true); |
||
| 223 | } |
||
| 224 | |||
| 225 | return $result; |
||
| 226 | } |
||
| 227 | |||
| 228 | /** |
||
| 229 | * Save task item. |
||
| 230 | * |
||
| 231 | * just one step more before saving task message that to support recurrence and task request here. We need |
||
| 232 | * to regenerate task if it is recurring and client has changed either set as complete or delete or |
||
| 233 | * given new start or end date. |
||
| 234 | * |
||
| 235 | * @param mapistore $store MAPI store of the message |
||
| 236 | * @param string $parententryid Parent entryid of the message (folder entryid, NOT message entryid) |
||
| 237 | * @param array $action Action array containing XML request |
||
| 238 | * @return array of PR_ENTRYID, PR_PARENT_ENTRYID and PR_STORE_ENTRYID properties of modified item |
||
| 239 | */ |
||
| 240 | function saveTask($store, $parententryid, $entryid, $action) |
||
| 241 | { |
||
| 242 | $properties = $this->properties; |
||
| 243 | $messageProps = array(); |
||
| 244 | $send = isset($action["message_action"]["send"]) ? $action["message_action"]["send"] : false; |
||
| 245 | |||
| 246 | if($store && $parententryid) { |
||
| 247 | if(isset($action["props"])) { |
||
| 248 | |||
| 249 | if (isset($action["entryid"]) && empty($action["entryid"])) { |
||
| 250 | $GLOBALS["operations"]->setSenderAddress($store, $action); |
||
| 251 | } |
||
| 252 | |||
| 253 | $props = $action["props"]; |
||
| 254 | $recips = array(); |
||
| 255 | if(isset($action["recipients"]) && is_array($action["recipients"])) { |
||
| 256 | $recips = $action["recipients"]; |
||
| 257 | } |
||
| 258 | |||
| 259 | if (isset($action["entryid"]) && !empty($action["entryid"])) { |
||
| 260 | $message = mapi_msgstore_openentry($store, hex2bin($action["entryid"])); |
||
| 261 | if ($message) { |
||
| 262 | $messageProps = mapi_getprops($message, array(PR_ENTRYID, PR_PARENT_ENTRYID, PR_STORE_ENTRYID, $properties['recurring'])); |
||
| 263 | |||
| 264 | if ((isset($messageProps[$properties['recurring']]) && $messageProps[$properties['recurring']]) || |
||
| 265 | (isset($props['recurring']) && $props['recurring'])) { |
||
| 266 | $recur = new TaskRecurrence($store, $message); |
||
| 267 | |||
| 268 | if (isset($props['recurring_reset']) && $props['recurring_reset'] == 1) { |
||
| 269 | $msgProps = $recur->setRecurrence($props); |
||
| 270 | } else if ((isset($props['complete']) && $props['complete'] == 1)) { |
||
| 271 | $msgProps = $recur->markOccurrenceComplete($props); |
||
| 272 | } |
||
| 273 | } |
||
| 274 | mapi_savechanges($message); |
||
| 275 | |||
| 276 | $messageProps = Conversion::mapXML2MAPI($properties, $props); |
||
| 277 | |||
| 278 | $message = $GLOBALS["operations"]->saveMessage($store, $entryid, $parententryid, $messageProps, $messageProps, $recips, isset($action['attachments']) ? $action['attachments'] : array(), array()); |
||
| 279 | |||
| 280 | if (isset($msgProps) && $msgProps) { |
||
| 281 | $messageProps = $msgProps; |
||
| 282 | } |
||
| 283 | } |
||
| 284 | } else { |
||
| 285 | $messageProps = Conversion::mapXML2MAPI($properties, $props); |
||
| 286 | //New message |
||
| 287 | |||
| 288 | $copyAttachments = false; |
||
| 289 | $copyFromMessage = false; |
||
| 290 | |||
| 291 | // we need to copy the original attachments when create task from message. |
||
| 292 | if (isset($action['message_action']) && isset($action['message_action']['source_entryid'])) { |
||
| 293 | $copyFromMessage = hex2bin($action['message_action']['source_entryid']); |
||
| 294 | $copyFromStore = hex2bin($action['message_action']['source_store_entryid']); |
||
| 295 | $copyAttachments = true; |
||
| 296 | |||
| 297 | // get resources of store and message |
||
| 298 | $copyFromStore = $GLOBALS['mapisession']->openMessageStore($copyFromStore); |
||
| 299 | $copyFromMessage = $GLOBALS['operations']->openMessage($copyFromStore, $copyFromMessage); |
||
| 300 | } |
||
| 301 | |||
| 302 | $message = $GLOBALS["operations"]->saveMessage($store, $entryid, $parententryid, $messageProps, $messageProps, $recips, isset($action['attachments']) ? $action['attachments'] : array(), array(), $copyFromMessage, $copyAttachments, false, false, false); |
||
| 303 | |||
| 304 | // Set recurrence |
||
| 305 | if (isset($action['props']['recurring']) && $action['props']['recurring'] == 1) { |
||
| 306 | $recur = new TaskRecurrence($store, $message); |
||
| 307 | $recur->setRecurrence($props); |
||
| 308 | } |
||
| 309 | } |
||
| 310 | |||
| 311 | if ($message) { |
||
| 312 | $tr = new TaskRequest($store, $message, $GLOBALS["mapisession"]->getSession()); |
||
| 313 | if ($send) { |
||
| 314 | $tr->sendTaskRequest(_("Task Request:") . " "); |
||
| 315 | |||
| 316 | return $messageProps; |
||
| 317 | } else if (isset($action["message_action"]["response_type"]) && $action["message_action"]["response_type"] === tdmtTaskUpd) { |
||
| 318 | $tr->doUpdate(); |
||
| 319 | |||
| 320 | return $messageProps; |
||
| 321 | } else if (isset($action["message_action"]["action_type"]) && $action["message_action"]["action_type"] === "restoreToTaskList") { |
||
| 322 | $deleteTRProps = $tr->deleteReceivedTR(); |
||
| 323 | if ($deleteTRProps) { |
||
| 324 | $GLOBALS["bus"]->notify(bin2hex($deleteTRProps[PR_PARENT_ENTRYID]), TABLE_DELETE, $deleteTRProps); |
||
| 325 | } |
||
| 326 | return $messageProps; |
||
| 327 | } |
||
| 328 | } |
||
| 329 | |||
| 330 | mapi_savechanges($message); |
||
| 331 | } |
||
| 332 | } |
||
| 333 | |||
| 334 | // Return message properties that can be sent to the bus to notify changes |
||
| 335 | return $messageProps; |
||
| 336 | } |
||
| 337 | } |
||
| 338 | ?> |
||
|
0 ignored issues
–
show
|
|||
| 339 |
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.