<?php

if (! defined('BASEPATH')) exit('No direct script access allowed');

/**
 * Messaging Library for FH-Complete
 */
class MessageLib
{
	const MSG_INDX_PREFIX = 'message_';

	private $_ci;

	/**
	 * Constructor
	 */
	public function __construct()
	{
		// Get code igniter instance
		$this->_ci =& get_instance();

		// Loads message configuration
		$this->_ci->config->load('message');

		// CI Parser library
		$this->_ci->load->library('parser');
		// Loads LogLib
		$this->_ci->load->library('LogLib');
		// Loads VorlageLib
		$this->_ci->load->library('VorlageLib');
		// Loads Mail library
		$this->_ci->load->library('MailLib');

		// Loading models
		$this->_ci->load->model('system/Message_model', 'MessageModel');
		$this->_ci->load->model('system/MsgStatus_model', 'MsgStatusModel');
		$this->_ci->load->model('system/Recipient_model', 'RecipientModel');
		$this->_ci->load->model('system/Attachment_model', 'AttachmentModel');

		// Loads phrases
		$this->_ci->lang->load('message');
	}

	//------------------------------------------------------------------------------------------------------------------
	// Public methods

	/**
	 * getMessage() - returns the specified received message for a specified person
	 */
	public function getMessage($msg_id, $person_id)
	{
		if (!is_numeric($msg_id))
			return $this->_error('', MSG_ERR_INVALID_MSG_ID);
		if (!is_numeric($person_id))
			return $this->_error('', MSG_ERR_INVALID_RECIPIENTS);

		return $this->_ci->RecipientModel->getMessage($msg_id, $person_id);
	}

	/**
	 * getMessagesByUID() - will return all messages, including the latest status for specified user. It don´t returns Attachments.
	 */
	public function getMessagesByUID($uid, $oe_kurzbz = null, $all = false)
	{
		if (isEmptyString($uid))
			return $this->_error('', MSG_ERR_INVALID_MSG_ID);

		return $this->_ci->RecipientModel->getMessagesByUID($uid, $oe_kurzbz, $all);
	}

	/**
	 * getMessagesByPerson() - will return all messages, including the latest status for specified user. It don´t returns Attachments.
	 */
	public function getMessagesByPerson($person_id, $oe_kurzbz = null, $all = false)
	{
		if (!is_numeric($person_id))
			return $this->_error('', MSG_ERR_INVALID_MSG_ID);

		return $this->_ci->RecipientModel->getMessagesByPerson($person_id, $oe_kurzbz, $all);
	}

	/**
	 * getSentMessagesByPerson() - Get all sent messages from a person identified by person_id
	 */
	public function getSentMessagesByPerson($person_id, $oe_kurzbz = null, $all = false)
	{
		if (!is_numeric($person_id))
			return $this->_error('', MSG_ERR_INVALID_MSG_ID);

		return $this->_ci->MessageModel->getMessagesByPerson($person_id, $oe_kurzbz, $all);
	}

	/**
	 * getMessageByToken
	 */
	public function getMessageByToken($token)
	{
		if (isEmptyString($token))
			return $this->_error('', MSG_ERR_INVALID_TOKEN);

		$result = $this->_ci->RecipientModel->getMessageByToken($token);
		if (hasData($result))
		{
			// Searches for a status that is different from unread
			$found = -1;
			for ($i = 0; $i < count($result->retval); $i++)
			{
				if ($result->retval[$i]->status > MSG_STATUS_UNREAD)
				{
					$found = $i;
					break;
				}
			}

			// If not found then insert the read status
			if ($found == -1)
			{
				$statusKey = array(
					'message_id' => $result->retval[0]->message_id,
					'person_id' => $result->retval[0]->receiver_id,
					'status' => MSG_STATUS_READ
				);

				$resultIns = $this->_ci->MsgStatusModel->insert($statusKey);
				// If an error occured while writing on data base, then return it
				if (isError($resultIns))
				{
					$result = $resultIns;
				}
			}
		}

		return $result;
	}

	/**
	 * getCountUnreadMessages
	 */
	public function getCountUnreadMessages($person_id, $oe_kurzbz = null)
	{
		if (!is_numeric($person_id))
			return $this->_error('', MSG_ERR_INVALID_RECIPIENTS);

		return $this->_ci->RecipientModel->getCountUnreadMessages($person_id, $oe_kurzbz);
	}

	/**
	 * updateMessageStatus() - will change status on message for particular user
	 * NOTE: it performs an insert, NOT an update
	 */
	public function updateMessageStatus($message_id, $person_id, $status)
	{
		if (!is_numeric($message_id))
		{
			return $this->_error('', MSG_ERR_INVALID_MSG_ID);
		}

		if (!is_numeric($person_id))
		{
			return $this->_error('', MSG_ERR_INVALID_USER_ID);
		}

		// NOTE: Not use empty otherwise if status is 0 it returns an error
		if (!isset($status))
		{
			return $this->_error('', MSG_ERR_INVALID_STATUS_ID);
		}

		// Searches if the status is already present
		$result = $this->_ci->MsgStatusModel->load(array($message_id, $person_id, $status));
		if (hasData($result))
		{
			// status already present
		}
		else
		{
			// Insert the new status
			$statusKey = array(
				'message_id' => $message_id,
				'person_id' => $person_id,
				'status' => $status
			);

			$result = $this->_ci->MsgStatusModel->insert($statusKey);
		}

		return $result;
	}

	/**
	 * sendMessage() - sends new internal message. This function will create a new thread
	 */
	public function sendMessage($sender_id, $receiver_id, $subject, $body, $priority = PRIORITY_NORMAL, $relationmessage_id = null, $oe_kurzbz = null, $multiPartMime = true)
	{
		if (!is_numeric($sender_id))
		{
			$sender_id = $this->_ci->config->item('system_person_id');
		}

		$receivers = $this->_getReceivers($receiver_id, $oe_kurzbz);

		// If everything went ok
		if (isSuccess($receivers) && is_array($receivers->retval))
		{
			// If no receivers were found for this organization unit
			if (count($receivers->retval) == 0)
			{
				$result = $this->_error($receivers->retval, MSG_ERR_OU_CONTACTS_NOT_FOUND);
			}

			// Looping on receivers
			for ($i = 0; $i < count($receivers->retval); $i++)
			{
				$receiver_id = $receivers->retval[$i]->person_id;

				// Checks if the receiver exists
				if ($this->_checkReceiverId($receiver_id))
				{
					// If the text and the subject of the template are not empty
					if (!isEmptyString($subject) && !isEmptyString($body))
					{
						$result = $this->_saveMessage($sender_id, $receiver_id, $subject, $body, $relationmessage_id, $oe_kurzbz);
						// If no errors were occurred
						// Leave the code commented
						if (isSuccess($result))
						{
							// If the system is configured to send messages immediately
							if ($this->_ci->config->item('send_immediately') === true)
							{
								// Send message by email!
								$resultSendEmail = $this->sendOne($result->retval, $subject, $body, $multiPartMime);
							}
						}
					}
					else
					{
						if (isEmptyString($subject))
						{
							$result = $this->_error('', MSG_ERR_SUBJECT_EMPTY);
							break;
						}
						elseif (isEmptyString($body))
						{
							$result = $this->_error('', MSG_ERR_BODY_EMPTY);
							break;
						}
					}
				}
				else
				{
					$result = $this->_error('', MSG_ERR_INVALID_RECEIVER_ID);
					break;
				}
			}
		}
		// If there was some errors then copy them into the returning variable
		else
		{
			$result = $receivers;
		}

		return $result;
	}

	/**
	 * Sends new internal message using a template
	 */
	public function sendMessageVorlage($sender_id, $receiver_id, $vorlage_kurzbz, $oe_kurzbz, $data, $relationmessage_id = null, $orgform_kurzbz = null, $multiPartMime = true)
	{
		if (!is_numeric($sender_id))
		{
			$sender_id = $this->_ci->config->item('system_person_id');
		}

		$receivers = $this->_getReceivers($receiver_id, $oe_kurzbz);

		// If everything went ok
		if (isSuccess($receivers) && is_array($receivers->retval))
		{
			// If no receivers were found for this organization unit
			if (count($receivers->retval) == 0)
			{
				$result = $this->_error($receivers->retval, MSG_ERR_OU_CONTACTS_NOT_FOUND);
			}
			else
			{
				// Load reveiver data to get its relative language
				$this->_ci->load->model('person/Person_model', 'PersonModel');
			}

			// Looping on receivers
			for ($i = 0; $i < count($receivers->retval); $i++)
			{
				$receiver_id = $receivers->retval[$i]->person_id;

				// Checks if the receiver exists
				$result = $this->_ci->PersonModel->load($receiver_id);
				if (hasData($result))
				{
					// Retrives the language of the logged user
					$sprache = getUserLanguage();

					// Loads template data
					$result = $this->_ci->vorlagelib->loadVorlagetext($vorlage_kurzbz, $oe_kurzbz, $orgform_kurzbz, $sprache);
					if (isSuccess($result))
					{
						// If the text and the subject of the template are not empty
						if (is_array($result->retval) && count($result->retval) > 0 &&
							!isEmptyString($result->retval[0]->text) && !isEmptyString($result->retval[0]->subject))
						{
							// Parses template text
							$parsedText = $this->_ci->vorlagelib->parseVorlagetext($result->retval[0]->text, $data);
							// Parses subject
							$subject = $this->_ci->vorlagelib->parseVorlagetext($result->retval[0]->subject, $data);

							// Save message
							$result = $this->_saveMessage($sender_id, $receiver_id, $subject, $parsedText, $relationmessage_id, $oe_kurzbz);
							// If no errors were occurred
							if (isSuccess($result))
							{
								// If the system is configured to send messages immediately
								if ($this->_ci->config->item('send_immediately') === true)
								{
									// Send message by email!
									$resultSendEmail = $this->sendOne($result->retval, $subject, $parsedText, $multiPartMime);
								}
							}
						}
						else
						{
							// Better message error
							if (!is_array($result->retval) || (is_array($result->retval) && count($result->retval) == 0))
							{
								$result = $this->_error('', MSG_ERR_TEMPLATE_NOT_FOUND);
								break;
							}
							elseif (is_array($result->retval) && count($result->retval) > 0)
							{
								if (is_null($result->retval[0]->oe_kurzbz))
								{
									$result = $this->_error('', MSG_ERR_TEMPLATE_NOT_FOUND);
									break;
								}
								elseif (isEmptyString($result->retval[0]->text))
								{
									$result = $this->_error('', MSG_ERR_INVALID_TEMPLATE);
									break;
								}
								elseif (isEmptyString($result->retval[0]->subject))
								{
									$result = $this->_error('', MSG_ERR_INVALID_TEMPLATE);
									break;
								}
							}
						}
					}
					else
					{
						$result = $this->_error($result->retval, EXIT_ERROR);
						break;
					}
				}
				else
				{
					$result = $this->_error('', MSG_ERR_INVALID_RECEIVER_ID);
					break;
				}
			}
		}
		// If there was some errors then copy them into the returning variable
		else
		{
			$result = $receivers;
		}

		return $result;
	}

	/**
	 * Gets all the messages from DB and sends them via email
	 */
	public function sendAll($numberToSent = null, $numberPerTimeRange = null, $email_time_range = null, $email_from_system = null)
	{
		$sent = true; // optimistic expectation

		// Gets standard configs
		$cfg = $this->_ci->maillib->getConfigs();
		$cfg->email_number_to_sent = $numberToSent;
		$cfg->email_number_per_time_range = $numberPerTimeRange;
		$cfg->email_time_range = $email_time_range;
		$cfg->email_from_system = $email_from_system;

		// Overrides configs with the parameters
		$this->_ci->maillib->overrideConfigs($cfg);

		// Gets a number ($this->_ci->maillib->getMaxEmailToSent()) of unsent messages from DB
		// having EMAIL_KONTAKT_TYPE as relative contact type
		$result = $this->_ci->RecipientModel->getMessages(
			EMAIL_KONTAKT_TYPE,
			null,
			$this->_ci->maillib->getConfigs()->email_number_to_sent
		);
		// Checks if errors were occurred
		if (isSuccess($result))
		{
			// If data are present
			if (is_array($result->retval) && count($result->retval) > 0)
			{
				// Iterating through the result set, if no errors occurred in the previous iteration
				for ($i = 0; $i < count($result->retval) && $sent; $i++)
				{
					// If the person has an email account
					if ((!is_null($result->retval[$i]->receiver) && $result->retval[$i]->receiver != '')
						|| (!is_null($result->retval[$i]->employeecontact) && $result->retval[$i]->employeecontact != ''))
					{
						$href = $this->_ci->config->item('message_server').$this->_ci->config->item('message_html_view_url').$result->retval[$i]->token;

						$vorlage = $this->_ci->vorlagelib->loadVorlagetext('MessageMailHTML');

						if(hasData($vorlage))
						{
							// Using a template for the html email body
							$body = $this->_ci->parser->parse_string(
								$vorlage->retval[0]->text,
								array(
									'href' => $href,
									'subject' => $result->retval[$i]->subject,
									'body' => $result->retval[$i]->body
								),
								true
							);
						}
						else
						{
							// Using a template for the html email body
							$body = $this->_ci->parser->parse(
								'templates/mailHTML',
								array(
									'href' => $href,
									'subject' => $result->retval[$i]->subject,
									'body' => $result->retval[$i]->body
								),
								true
							);
						}
						if (is_null($body) || $body == '')
						{
							$this->_ci->loglib->logError('Error while parsing the mail template');
						}

						$vorlage = $this->_ci->vorlagelib->loadVorlagetext('MessageMailTXT');
						if(hasData($vorlage))
						{
							// Using a template for the plain text email body
							$altBody = $this->_ci->parser->parse_string(
								$vorlage->retval[0]->text,
								array(
									'href' => $href,
									'subject' => $result->retval[$i]->subject,
									'body' => $result->retval[$i]->body
								),
								true
							);
						}
						else
						{
							// Using a template for the plain text email body
							$altBody = $this->_ci->parser->parse(
								'templates/mailTXT',
								array(
									'href' => $href,
									'subject' => $result->retval[$i]->subject,
									'body' => $result->retval[$i]->body
								),
								true
							);
						}
						if (is_null($altBody) || $altBody == '')
						{
							$this->_ci->loglib->logError('Error while parsing the mail template');
						}

						// If the sender is not an employee, then system-sender is used if empty
						$sender = '';
						if (!is_null($result->retval[0]->senderemployeecontact) && $result->retval[0]->senderemployeecontact != '')
						{
							$sender = $result->retval[0]->senderemployeecontact.'@'.DOMAIN;
						}

						$receiverContact = $result->retval[$i]->receiver;
						if (!is_null($result->retval[$i]->employeecontact) && $result->retval[$i]->employeecontact != '')
						{
							$receiverContact = $result->retval[$i]->employeecontact.'@'.DOMAIN;
						}

						// Sending email
						$sent = $this->_ci->maillib->send(
							$sender,
							$receiverContact,
							$result->retval[$i]->subject,
							$body,
							null,
							null,
							null,
							$altBody
						);
						// If errors were occurred while sending the email
						if (!$sent)
						{
							$this->_ci->loglib->logError('Error while sending an email');
							// Writing errors in tbl_msg_recipient
							$sme = $this->setMessageError(
								$result->retval[$i]->message_id,
								$result->retval[$i]->receiver_id,
								'Error while sending an email',
								$result->retval[$i]->sentinfo
							);
							if (!$sme)
							{
								$this->_ci->loglib->logError('Error while updating DB');
							}
						}
						else
						{
							// Setting the message as sent in DB
							$sent = $this->setMessageSent($result->retval[$i]->message_id, $result->retval[$i]->receiver_id);
							// If some errors occurred
							if (!$sent)
							{
								$this->_ci->loglib->logError('Error while updating DB');
							}
						}
					}
					else
					{
						$this->_ci->loglib->logError('This person does not have an email account');
						// Writing errors in tbl_msg_recipient
						$sme = $this->setMessageError(
							$result->retval[$i]->message_id,
							$result->retval[$i]->receiver_id,
							'This person does not have an email account',
							$result->retval[$i]->sentinfo
						);
						if (!$sme)
						{
							$this->_ci->loglib->logError('Error while updating DB');
						}
						$sent = true; // Non blocking error
					}
				}
			}
			else
			{
				$this->_ci->loglib->logInfo('There are no email to be sent');
				$sent = false;
			}
		}
		else
		{
			$this->_ci->loglib->logError('Something went wrong while getting data from DB');
			$sent = false;
		}

		return $sent;
	}

	/**
	 * Gets one message from DB and sends it via email
	 */
	public function sendOne($message_id, $subject = null, $body = null, $multiPartMime = true)
	{
		$sent = true; // optimistic expectation

		// Get a specific message from DB having EMAIL_KONTAKT_TYPE as relative contact type
		$result = $this->_ci->RecipientModel->getMessages(
			EMAIL_KONTAKT_TYPE,
			null,
			null,
			$message_id
		);

		// Checks if errors were occurred
		if (isSuccess($result))
		{
			// If data are present
			if (is_array($result->retval) && count($result->retval) > 0)
			{
				// If the person has an email account
				if ((!is_null($result->retval[0]->receiver) && $result->retval[0]->receiver != '')
					|| (!is_null($result->retval[0]->employeecontact) && $result->retval[0]->employeecontact != ''))
				{
					// If it is required use a multi-part message in MIME format
					if ($multiPartMime === true)
					{
						// Using a template for the html email body
						$href = $this->_ci->config->item('message_server').$this->_ci->config->item('message_html_view_url').$result->retval[0]->token;

						$vorlage = $this->_ci->vorlagelib->loadVorlagetext('MessageMailHTML');
						if(hasData($vorlage))
						{
							$bodyMsg = $this->_ci->parser->parse_string(
								$vorlage->retval[0]->text,
								array(
									'href' => $href,
									'subject' => $result->retval[0]->subject,
									'body' => $result->retval[0]->body
								),
								true
							);
						}
						else
						{
							$bodyMsg = $this->_ci->parser->parse(
								'templates/mailHTML',
								array(
									'href' => $href,
									'subject' => $result->retval[0]->subject,
									'body' => $result->retval[0]->body
								),
								true
							);
						}
						if (is_null($bodyMsg) || $bodyMsg == '')
						{
							// $body = $result->retval[0]->body;
							$this->_ci->loglib->logError('Error while parsing the html mail template');
						}

						// Using a template for the plain text email body
						$vorlage = $this->_ci->vorlagelib->loadVorlagetext('MessageMailTXT');
						if(hasData($vorlage))
						{
							$altBody = $this->_ci->parser->parse_string(
								$vorlage->retval[0]->text,
								array(
									'href' => $href,
									'subject' => $result->retval[0]->subject,
									'body' => $result->retval[0]->body
								),
								true
							);
						}
						else
						{
							$altBody = $this->_ci->parser->parse(
								'templates/mailTXT',
								array(
									'href' => $href,
									'subject' => $result->retval[0]->subject,
									'body' => $result->retval[0]->body
								),
								true
							);
						}
						if (is_null($altBody) || $altBody == '')
						{
							$this->_ci->loglib->logError('Error while parsing the plain text mail template');
						}
					}
					else
					{
						$bodyMsg = $altBody = $body;
					}

					// If the sender is not an employee, then system-sender is used if empty
					$sender = '';
					if (!is_null($result->retval[0]->senderemployeecontact) && $result->retval[0]->senderemployeecontact != '')
					{
						$sender = $result->retval[0]->senderemployeecontact.'@'.DOMAIN;
					}

					$receiverContact = $result->retval[0]->receiver;
					if (!is_null($result->retval[0]->employeecontact) && $result->retval[0]->employeecontact != '')
					{
						$receiverContact = $result->retval[0]->employeecontact.'@'.DOMAIN;
					}

					// Sending email
					$sent = $this->_ci->maillib->send(
						null,
						$receiverContact,
						is_null($subject) ? $result->retval[0]->subject : $subject, // if parameter subject is not null, use it!
						$bodyMsg,
						null,
						null,
						null,
						$altBody
					);
					// If errors were occurred while sending the email
					if (!$sent)
					{
						$this->_ci->loglib->logError('Error while sending an email');
						// Writing errors in tbl_msg_recipient
						$sme = $this->setMessageError(
							$result->retval[0]->message_id,
							$result->retval[0]->receiver_id,
							'Error while sending an email',
							$result->retval[0]->sentinfo
						);
						if (!$sme)
						{
							$this->_ci->loglib->logError('Error while updating DB');
						}
					}
					else
					{
						// Setting the message as sent in DB
						$sent = $this->setMessageSent($result->retval[0]->message_id, $result->retval[0]->receiver_id);
						// If the email has been sent and the DB updated
						if (!$sent)
						{
							$this->_ci->loglib->logError('Error while updating DB');
						}
					}
				}
				else
				{
					$this->_ci->loglib->logError('This person does not have an email account');
					// Writing errors in tbl_msg_recipient
					$sme = $this->setMessageError(
						$result->retval[0]->message_id,
						$result->retval[0]->receiver_id,
						'This person does not have an email account',
						$result->retval[0]->sentinfo
					);
					if (!$sme)
					{
						$this->_ci->loglib->logError('Error while updating DB');
					}
					$sent = true; // Non blocking error
				}
			}
			else
			{
				$this->_ci->loglib->logInfo('There are no email to be sent');
				$sent = false;
			}
		}
		else
		{
			$this->_ci->loglib->logError('Something went wrong while getting data from DB');
			$sent = false;
		}

		return $sent;
	}

	/**
	 * parseMessageText
	 */
	public function parseMessageText($text, $data = array())
	{
		$tmpData = array();

		// Replaces data array keys to a lowercase without spaces string
		foreach ($data as $key => $val)
		{
			$tmpData[str_replace(' ', '_', strtolower($key))] = $data[$key];
		}

		return $this->_ci->parser->parse_string($text, $tmpData, true);
	}

	/**
	 * Gets data for Person from view vw_msg_vars_person
	 * @param $person_id
	 */
	public function getMessageVarsPerson()
	{
		$variablesArray = array();
		$variables = $this->_ci->MessageModel->getMessageVarsPerson();

		if (isError($variables))
		{
			show_error($variables->retval);
		}
		elseif (hasData($variables))
		{
			// Skip person_id
			for ($i = 1; $i < count($variables->retval); $i++)
			{
				$variablesArray['{'.str_replace(' ', '_', strtolower($variables->retval[$i])).'}'] = $variables->retval[$i];
			}
			array_shift($variables->retval); // Remove person_id
		}

		return $variablesArray;
	}

	/**
	 * A person may belongs to more organisation units
	 */
	public function getOeKurzbz($sender_id)
	{
		$oe_kurzbz = array();

		$this->_ci->load->model('person/Benutzerfunktion_model', 'BenutzerfunktionModel');
 		$benutzerResult = $this->_ci->BenutzerfunktionModel->getByPersonId($sender_id);
		if (isError($benutzerResult))
		{
			show_error($benutzerResult->retval);
		}
 		elseif (hasData($benutzerResult))
 		{
 			foreach ($benutzerResult->retval as $val)
 			{
 				$oe_kurzbz[] = $val->oe_kurzbz;
 			}
 		}

		return $oe_kurzbz;
	}

	/**
	 * Admin or commoner?
	 */
	public function getIsAdmin($sender_id)
	{
		$this->_ci->load->model('system/Benutzerrolle_model', 'BenutzerrolleModel');
 		$isAdmin = $this->_ci->BenutzerrolleModel->isAdminByPersonId($sender_id);
 		if (isError($isAdmin))
 		{
 			show_error($isAdmin->retval);
 		}

		return $isAdmin->retval;
	}

	/**
	 *
	 */
	public function send()
	{

	}

	//------------------------------------------------------------------------------------------------------------------
	// Private methods

	/**
	 * Update the table tbl_msg_recipient
	 */
	private function _updateMessageRecipient($message_id, $receiver_id, $parameters)
	{
		$updated = false;

		// Updates table tbl_msg_recipient
		$resultUpdate = $this->_ci->RecipientModel->update(array($receiver_id, $message_id), $parameters);
		// Checks if errors were occurred
		if (isSuccess($resultUpdate) && is_array($resultUpdate->retval))
		{
			$updated = true;
		}

		return $updated;
	}

	/**
	 * Changes the status of the message from unsent to sent
	 */
	private function setMessageSent($message_id, $receiver_id)
	{
		$parameters = array('sent' => 'NOW()', 'sentinfo' => null);

		return $this->_updateMessageRecipient($message_id, $receiver_id, $parameters);
	}

	/**
	 * Sets the sentInfo with the error
	 */
	private function setMessageError($message_id, $receiver_id, $sentInfo, $prevSentInfo = null)
	{
		if (!is_null($prevSentInfo) && $prevSentInfo != '')
		{
			$sentInfo = $prevSentInfo.SENT_INFO_NEWLINE.$sentInfo;
		}

		$parameters = array('sent' => null, 'sentinfo' => $sentInfo);

		return $this->_updateMessageRecipient($message_id, $receiver_id, $parameters);
	}

	/**
	 * Gets the receivers id that are enabled to read messages for that oe_kurzbz
	 */
	private function _getReceiversByOekurzbz($oe_kurzbz)
	{
		// Load Benutzerfunktion_model
		$this->_ci->load->model('person/Benutzerfunktion_model', 'BenutzerfunktionModel');
		// Join with table public.tbl_benutzer on field uid
		$this->_ci->BenutzerfunktionModel->addJoin('public.tbl_benutzer', 'uid');
		// Get all the valid receivers id using the oe_kurzbz
		$receivers = $this->_ci->BenutzerfunktionModel->loadWhere(
			'oe_kurzbz = '.$this->_ci->db->escape($oe_kurzbz).
			' AND funktion_kurzbz = '.$this->_ci->db->escape($this->_ci->config->item('assistent_function')).
			' AND (NOW() BETWEEN COALESCE(datum_von, NOW()) AND COALESCE(datum_bis, NOW()))'
		);

		return $receivers;
	}

	/**
	 * Gets the receivers id
	 */
	private function _getReceivers($receiver_id, $oe_kurzbz = null)
	{
		$receivers = null;

		// If no receiver_id is given...
		if (is_null($receiver_id))
		{
			// ...a oe_kurzbz must be specified
			if (is_null($oe_kurzbz))
			{
				$receivers = $this->_error('', MSG_ERR_INVALID_OU);
			}
			else
			{
				$receivers = $this->_getReceiversByOekurzbz($oe_kurzbz);
			}
		}
		// Else if the receiver id is given
		else
		{
			$receivers = $this->_success(array(new stdClass()));
			$receivers->retval[0]->person_id = $receiver_id;
		}

		return $receivers;
	}

	/**
	 * Checks if the given receiver id is a valid person
	 */
	private function _checkReceiverId($receiver_id)
	{
		// Load Person_model
		$this->_ci->load->model('person/Person_model', 'PersonModel');
		$result = $this->_ci->PersonModel->load($receiver_id);
		if (hasData($result))
		{
			return true;
		}

		return false;
	}

	/**
	 * Save a message in DB
	 **/
	private function _saveMessage($sender_id, $receiver_id, $subject, $body, $relationmessage_id, $oe_kurzbz)
	{
		// Starts db transaction
		$this->_ci->db->trans_start(false);

		// Save Message
		$msgData = array(
			'person_id' => $sender_id,
			'subject' => $subject,
			'body' => $body,
			'priority' => PRIORITY_NORMAL,
			'relationmessage_id' => $relationmessage_id,
			'oe_kurzbz' => $oe_kurzbz
		);
		$result = $this->_ci->MessageModel->insert($msgData);
		if (isSuccess($result))
		{
			// Link the message with the receiver
			$msg_id = $result->retval;
			$recipientData = array(
				'person_id' => $receiver_id,
				'message_id' => $msg_id,
				'token' => generateToken()
			);
			$result = $this->_ci->RecipientModel->insert($recipientData);
			if (isSuccess($result))
			{
				// Save message status
				$statusData = array(
					'message_id' => $msg_id,
					'person_id' => $receiver_id,
					'status' => MSG_STATUS_UNREAD
				);
				$result = $this->_ci->MsgStatusModel->insert($statusData);
			}
		}

		$this->_ci->db->trans_complete();

		if ($this->_ci->db->trans_status() === false || isError($result))
		{
			$this->_ci->db->trans_rollback();
			$result = $this->_error($result->msg, EXIT_ERROR);
		}
		else
		{
			$this->_ci->db->trans_commit();
			$result = $this->_success($msg_id);
		}

		return $result;
	}

	/**
	 * Wrapper for function error
	 */
	private function _error($retval = '', $code = null)
	{
		return error($retval, $code, MessageLib::MSG_INDX_PREFIX);
	}

	/**
	 * Wrapper for function success
	 */
	private function _success($retval = '', $code = null)
	{
		return success($retval, $code, MessageLib::MSG_INDX_PREFIX);
	}
}
