<?php
	/**
	 * Create Mail ItemModule
	 * Module which openes, creates, saves and deletes an item. It 
	 * extends the Module class.
	 */
	class CreateMailItemModule extends ItemModule
	{
		/**
		 * Constructor
		 * @param int $id unique id.
		 * @param array $data list of all actions.
		 */
		function CreateMailItemModule($id, $data)
		{
			$this->properties = $GLOBALS["properties"]->getMailProperties();
			
			parent::ItemModule($id, $data);
		}
		
		/**
		 * Function which saves and/or sends an item.
		 * @param object $store MAPI Message Store Object
		 * @param string $parententryid parent entryid of the message
		 * @param string $entryid entryid of the message
		 * @param array $action the action data, sent by the client
		 * @return boolean true on success or false on failure		 		 
		 */
		function save($store, $parententryid, $entryid, $action)
		{
			global $state;
			$result = false;
			$send = false;

			if(!$store) {
				$store = $GLOBALS["mapisession"]->getDefaultMessageStore();
			}
			if(!$parententryid) {
				if(isset($action["props"]["message_class"])) {
					$parententryid = $this->getDefaultFolderEntryID($store, $action["props"]["message_class"]);
				} else {
					$parententryid = $this->getDefaultFolderEntryID($store, '');
				}
			}
			
			if($store) {
				if(isset($action["props"])){
					$messageProps = array();

					$send = false;
					if(isset($action["message_action"]) && isset($action["message_action"]["send"])) {
						$send = $action["message_action"]["send"];
					}

					$copyAttachments = false;
					$copyFromMessageId = false;
					$copyFromStore = false;
					$copyOnlyInlineAttachments = false;
					$replyOrigMessageDetails = false;

					if(isset($action["message_action"]) && isset($action["message_action"]["action_type"])) {
						$actions = array("reply", "replyall", "forward", "edit");
						if (array_search($action["message_action"]["action_type"], $actions) !== false) {
							/**
							 * we need to copy the original attachments when it is an forwarded message
							 * OR
							 * we need to copy ONLY original inline(HIDDEN) attachments when it is reply/replyall message
							 */
							$copyFromMessageId = hex2bin($action["message_action"]["source_entryid"]);
							$copyFromStore = hex2bin($action["message_action"]["source_store_entryid"]);
							// Open store (this => $GLOBALS['mapisession'])
							$copyFromStore = $GLOBALS['mapisession']->openMessageStore($copyFromStore);
							$copyAttachments = true;

							if ($action["message_action"]["action_type"] != "forward") {
								$copyOnlyInlineAttachments = true;
								$replyOrigMessageDetails = array(
									"source_entryid"=>$action["message_action"]["source_entryid"],
									"source_store_entryid"=>$action["message_action"]["source_store_entryid"]
								);
							}
						}
					}

					if(isset($action['props']['message_flags']) && $entryid) {
						$msg_action = isset($action['message_action']) ? $action['message_action'] : false;
						$GLOBALS['operations']->setMessageFlag($store, $entryid, $action['props']['message_flags'], $msg_action);
					}

					if($send) {
						$prop = Conversion::mapXML2MAPI($this->properties, $action["props"]);

						$result = $GLOBALS["operations"]->submitMessage($store, $entryid, Conversion::mapXML2MAPI($this->properties, $action["props"]), $messageProps, isset($action['recipients']) ? $action['recipients'] : array(), isset($action['attachments']) ? $action['attachments'] : array(), $copyFromMessageId, $copyFromStore, $copyAttachments, false, $copyOnlyInlineAttachments, $replyOrigMessageDetails);
						
						// If draft is send from the drafts folder, delete notification
						if($result) {
							if(isset($entryid) && !empty($entryid)) {
								$props = array();
								$props[PR_ENTRYID] = $entryid;
								$props[PR_PARENT_ENTRYID] = $parententryid;
								
								$storeprops = mapi_getprops($store, array(PR_ENTRYID));
								$props[PR_STORE_ENTRYID] = $storeprops[PR_ENTRYID];
								
								$GLOBALS["bus"]->notify(bin2hex($parententryid), TABLE_DELETE, $props);
							}
						}
					} else {
						if ($entryid == false && isset($action['attachments']) && isset($action['attachments']['dialog_attachments'])) {
							$entryid = $state->read("createmail".$action['attachments']['dialog_attachments']);
						}

						$result = $GLOBALS["operations"]->saveMessage($store, $entryid, $parententryid, Conversion::mapXML2MAPI($this->properties, $action["props"]), $messageProps, isset($action['recipients']) ? $action['recipients'] : array(), isset($action['attachments']) ? $action['attachments'] : array(), array(), $copyFromMessageId, $copyFromStore, $copyAttachments, false, $copyOnlyInlineAttachments);

						if(isset($action['attachments']) && isset($action['attachments']['dialog_attachments'])) {
							$state->write("createmail".$action['attachments']['dialog_attachments'], bin2hex($messageProps[PR_ENTRYID]));
						}

						// Update the client with the (new) entryid and parententryid to allow the draft message to be removed when submitting.
						// Retrieve entryid and parententryid of new mail.
						$props = array();
						$props = mapi_getprops($result, array(PR_ENTRYID, PR_PARENT_ENTRYID, PR_STORE_ENTRYID, PR_MESSAGE_CLASS, PR_OBJECT_TYPE));
						$savedMsg = $GLOBALS['operations']->openMessage($store, $props[PR_ENTRYID]);
						$data = array();
						$data["item"] = $GLOBALS["operations"]->getMessageProps($store, $savedMsg, $this->properties, false);

						$this->addActionData("update", $data);
						$GLOBALS["bus"]->addData($this->getResponseData());
					}

					// Reply/Reply All/Forward Actions (ICON_INDEX & LAST_VERB_EXECUTED)
					if(isset($action["message_action"]) && isset($action["message_action"]["action_type"]) && $action["message_action"]["action_type"] != "forwardasattachment"
						&& isset($action["message_action"]["source_entryid"])) {
						$props = array();
						$props[$this->properties["entryid"]] = hex2bin($action["message_action"]["source_entryid"]);

						switch($action["message_action"]["action_type"])
						{
							case "reply":
								$props[$this->properties["icon_index"]] = 261;
								$props[$this->properties["last_verb_executed"]] = 102;
								break;
							case "replyall":
								$props[$this->properties["icon_index"]] = 261;
								$props[$this->properties["last_verb_executed"]] = 103;
								break;
							case "forward":
								$props[$this->properties["icon_index"]] = 262;
								$props[$this->properties["last_verb_executed"]] = 104;
								break;
						}
						
						$props[$this->properties["last_verb_execution_time"]] = time();
						
						// Use the storeid of that belongs to the message_action entryid.
						// This is in case the message is on another store.
						$storeOrigMsg = $GLOBALS["mapisession"]->openMessageStore(hex2bin($action["message_action"]["source_store_entryid"]));

						$messageActionProps = array();
						$messageActionResult = $GLOBALS["operations"]->saveMessage($storeOrigMsg, $props[PR_ENTRYID], $parententryid, $props, $messageActionProps);

						if($messageActionResult) {
							if(isset($messageActionProps[PR_PARENT_ENTRYID])) {
								$GLOBALS["bus"]->notify(bin2hex($messageActionProps[PR_PARENT_ENTRYID]), TABLE_SAVE, $messageActionProps);
							}
						}
					}
				}
				if($result && !$send) {
					$GLOBALS["bus"]->notify(bin2hex($messageProps[PR_PARENT_ENTRYID]), TABLE_SAVE, $messageProps);
				}

				// Send success message to client, only when you are sending a mail, not when saving it
				if($send) {
					//$this->sendFeedback(true);
					$this->addActionData("update", array("item" => Conversion::mapMAPI2XML($this->properties, $messageProps)));
					$GLOBALS["bus"]->addData($this->getResponseData());
				}
			}
		}
	}
?>
