<?php
namespace PHPFusion;
if (!defined("IN_FUSION")) { die("Access Denied"); }

class PrivateMessages {
	private $info = array();

	/**
	 * @return array
	 */
	public function getInfo() {
		return $this->info;
	}

    public function display_inbox() {
        global $locale, $userdata;
        $this->setInbox();
        if ($_GET['folder'] == "options") {
            $this->display_settings();
        } else {

            add_to_title($locale['global_201'].$this->info['folders'][$_GET['folder']]['title']);

            set_meta("description", $this->info['folders'][$_GET['folder']]['title']);

            $query = array(
                "outbox" => array($this->info['outbox_total'], "message_folder='1'"),
                "inbox" => array($this->info['inbox_total'], "message_folder='0'"),
                "archive" => array($this->info['archive_total'], "message_folder='2'"),
            );

            if ($query[$_GET['folder']][0] > 0) {

                // Get messages
                $result = dbquery("SELECT m.*,
                u.user_id, u.user_name, u.user_status, u.user_avatar,
                max(m.message_id) as last_message
                FROM ".DB_MESSAGES." m
                LEFT JOIN ".DB_USERS." u ON (m.message_from=u.user_id)
                WHERE message_to='".$userdata['user_id']."' and ".$query[$_GET['folder']][1]."
                group by message_id
                ORDER BY m.message_datestamp DESC
                ");

                $this->info['max_rows'] = dbrows($result);
                if ($this->info['max_rows']) {
                    while ($data = dbarray($result)) {

                        $data['contact_user'] = array(
                            'user_id' => $data['user_id'],
                            'user_name' => $data['user_name'],
                            'user_status' => $data['user_status'],
                            'user_avatar' => $data['user_avatar']
                        );

                        $data['message'] = array(
                            "link" => BASEDIR."messages.php?folder=".$_GET['folder']."&amp;msg_read=".$data['message_id'],
                            "name" => $data['message_subject'],
                            "message_header" => "<strong>".$locale['462'].":</strong> ".$data['message_subject'],
                            "message_text" => $data['message_smileys'] == "y" ? parseubb(parsesmileys($data['message_message'])) : parseubb($data['message_message']),
                        );

                        $this->info['items'][$data['message_id']] = $data;
                    }
                    // set read
                    if (isset($_GET['msg_read']) && isnum($_GET['msg_read']) && isset($this->info['items'][$_GET['msg_read']])) {
                        dbquery("UPDATE ".DB_MESSAGES." SET message_read='1' WHERE message_id='".intval($_GET['msg_read'])."'");
                    }
                } else {
                    $this->info['no_item'] = $locale['471'];
                }
            } else {
                $this->info['no_item'] = $locale['471'];
            }

            // Message Actions
            if (isset($_POST['archive_pm'])) {
                $this->archive_pm();
            } elseif (isset($_POST['unarchive_pm'])) {
                $this->unarchive_pm();
            } elseif (isset($_POST['delete_pm'])) {
                $this->delete_pm();
            } elseif (isset($_POST['mark'])) {
                $this->mark_pm();
            }
            // The UI actions
            // Actions buttons - archive, delete, mark all read, mark all unread, mark as read, mark as unread
            ob_start();
            if (isset($_GET['msg_read'])) {
                echo openform("actionform", "post",
                              BASEDIR."messages.php?folder=".$_GET['folder'].(isset($_GET['msg_read']) ? "&amp;msg_read=".$_GET['msg_read'] : ""),
                              array("class" => "display-inline-block m-l-10"));
                echo form_hidden("selectedPM", "", $_GET['msg_read']);
                echo "<div class='btn-group display-inline-block m-r-10'>\n";
                if ($_GET['folder'] == "archive") {
                    echo form_button("unarchive_pm", "", "archive_pm", array("icon" => "fa fa-unlock"));
                } elseif ($_GET['folder'] == "inbox") {
                    echo form_button("archive_pm", "", "archive_pm", array("icon" => "fa fa-lock"));
                }
                echo form_button("delete_pm", "", "delete_pm", array("icon" => "fa fa-trash-o"));
                echo "</div>\n";
                echo closeform();
            } else {
                echo openform("actionform", "post", BASEDIR."messages.php?folder=".$_GET['folder'].(isset($_GET['msg_read']) ? "&amp;msg_read=".$_GET['msg_read'] : ""));
                ?>
                <!-- pm_idx -->
                <div class="dropdown display-inline-block m-r-10">
                    <a href="#" data-toggle="dropdown" class="btn btn-default dropdown-toggle"><i id="chkv"
                                                                                                  class="fa fa-square-o"></i>
                        <span class="caret"></span></a>
                    <ul class="dropdown-menu">
                        <li><a id="check_all_pm" data-action="check" class="pointer"><?php echo $locale['418'] ?></a>
                        </li>
                        <li><a id="check_unread_pm" data-action="check" class="pointer"><?php echo $locale['415'] ?></a>
                        </li>
                        <li><a id="check_read_pm" data-action="check" class="pointer"><?php echo $locale['414'] ?></a>
                        </li>
                    </ul>
                </div>
                <?php
                echo form_hidden("selectedPM", "", "");
                echo "<div class='btn-group display-inline-block m-r-10'>\n";
                if ($_GET['folder'] == 'archive') {
                echo form_button("unarchive_pm", "", "unarchive_pm", array("icon" => "fa fa-unlock"));
                } else {
                    if ($_GET['folder'] !== 'outbox') {
                        echo form_button("archive_pm", "", "archive_pm", array("icon" => "fa fa-lock"));
                    }
                }
                echo form_button("delete_pm", "", "delete_pm", array("icon" => "fa fa-trash-o"));
                echo "</div>\n";
                ?>
                <div class="dropdown display-inline-block m-r-10">
                    <a href="#" data-toggle="dropdown"
                       class="btn btn-default dropdown-toggle"><?php echo $locale['444'] ?>&hellip; <span
                            class="caret"></span></a>
                    <ul class="dropdown-menu">
                        <li><?php echo form_button("mark", $locale['493'], "mark_all",
                                                   array("class" => "btn-link")) ?></li>
                        <li><?php echo form_button("mark", $locale['494'], "mark_read",
                                                   array("class" => "btn-link")) ?></li>
                        <li><?php echo form_button("mark", $locale['495'], "mark_unread",
                                                   array("class" => "btn-link")) ?></li>
                        <li><?php echo form_button("mark", $locale['496'], "unmark_all",
                                                   array("class" => "btn-link")) ?></li>
                    </ul>
                </div>
                <?php
                echo closeform();
                add_to_jquery("
                function checkedCheckbox() {
                    var checkList = '';
                    $('input[type=checkbox]').each(function() {
                        if (this.checked) {
                            checkList += $(this).val()+',';
                        }
                    });
                    return checkList;
                }
                $('#check_all_pm').bind('click', function() {
                    var unread_checkbox = $('#unread_tbl tr').find(':checkbox');
                    var read_checkbox = $('#read_tbl tr').find(':checkbox');
                    var action = $(this).data('action');
                    if (action == 'check') {
                        unread_checkbox.prop('checked', true);
                        read_checkbox.prop('checked', true);
                        $('#unread_tbl tr').addClass('warning');
                        $('#read_tbl tr').addClass('warning');
                        $('#chkv').removeClass('fa fa-square-o').addClass('fa fa-minus-square-o');
                        $(this).data('action', 'uncheck');
                        $('#selectedPM').val(checkedCheckbox());
                    } else {
                        unread_checkbox.prop('checked', false);
                        read_checkbox.prop('checked', false);
                        $('#unread_tbl tr').removeClass('warning');
                        $('#read_tbl tr').removeClass('warning');
                        $('#chkv').removeClass('fa fa-minus-square-o').addClass('fa fa-square-o');
                        $(this).data('action', 'check');
                        $('#selectedPM').val(checkedCheckbox());
                    }
                });
                $('#check_read_pm').bind('click', function() {
                    var read_checkbox = $('#read_tbl tr').find(':checkbox');
                    var action = $(this).data('action');
                    if (action == 'check') {
                        read_checkbox.prop('checked', true);
                        $('#read_tbl tr').addClass('warning');
                        $('#chkv').removeClass('fa fa-square-o').addClass('fa fa-minus-square-o');
                        $(this).data('action', 'uncheck');
                        $('#selectedPM').val(checkedCheckbox());
                    } else {
                        read_checkbox.prop('checked', false);
                        $('#read_tbl tr').removeClass('warning');
                        $('#chkv').removeClass('fa fa-minus-square-o').addClass('fa fa-square-o');
                        $(this).data('action', 'check');
                        $('#selectedPM').val(checkedCheckbox());
                    }
                });
                $('#check_unread_pm').bind('click', function() {
                    var unread_checkbox = $('#unread_tbl tr').find(':checkbox');
                    var action = $(this).data('action');
                    if (action == 'check') {
                        unread_checkbox.prop('checked', true);
                        $('#unread_tbl tr').addClass('warning');
                        $('#chkv').removeClass('fa fa-square-o').addClass('fa fa-minus-square-o');
                        $(this).data('action', 'uncheck');
                        $('#selectedPM').val(checkedCheckbox());
                    } else {
                        unread_checkbox.prop('checked', false);
                        $('#unread_tbl tr').removeClass('warning');
                        $('#chkv').removeClass('fa fa-minus-square-o').addClass('fa fa-square-o');
                        $(this).data('action', 'check');
                        $('#selectedPM').val(checkedCheckbox());
                    }
                });
		        ");
                add_to_jquery("
                $('input[type=checkbox]').bind('click', function() {
                    var checkList = $('#selectedPM').val();
                    if ($(this).is(':checked')) {
                    $(this).parents('tr').addClass('warning');
                        checkList += $(this).val()+',';
                    } else {
                        $(this).parents('tr').removeClass('warning');
                        checkList = checkList.replace($(this).val()+',', '');
                    }
                    $('#selectedPM').val(checkList);
                });
                ");
            }
            $this->info['actions_form'] = ob_get_contents();
            ob_end_clean();
            // The mail forms
            if (isset($_GET['msg_read']) || isset($_GET['msg_send'])) {
                if (isset($_POST['send_pm']) || isset($_POST['send_message'])) {
                    $this->send_message();
                }
                if (isset($_GET['msg_read'])) {
                    $this->pm_form();
                } elseif (isset($_GET['msg_send'])) {
                    $this->pm_mainForm();
                }
            }
        }
    }

    private function setInbox() {
        global $locale, $userdata;
        /**
         * Sanitize environment
         */
        $myStatus = self::get_pm_settings($userdata['user_id']);
        //print_p($myStatus);
        if (!isset($_GET['folder']) || !preg_check("/^(inbox|outbox|archive|options)$/", $_GET['folder'])) {
            $_GET['folder'] = "inbox";
        }
        function validate_user($user_id) {
            if (isnum($user_id) && dbcount("(user_id)", DB_USERS,
                                           "user_id='".intval($user_id)."' AND user_status ='0'")
            ) {
                return TRUE;
            }

            return FALSE;
        }

        if (isset($_POST['msg_send']) && isnum($_POST['msg_send']) && validate_user($_POST['msg_send'])) {
            $_GET['msg_send'] = $_POST['msg_send'];
        }
        // prohibits send message to non-existing group
        $user_group = fusion_get_groups();
        unset($user_group[0]);
        if (isset($_POST['msg_to_group']) && isnum($_POST['msg_to_group']) && isset($user_group[$_POST['msg_to_group']])) {
            $_GET['msg_to_group'] = $_POST['msg_to_group'];
        }
        $this->info = array(
            "folders" => array(
                "inbox"   => array("link" => BASEDIR."messages.php?folder=inbox", "title" => $locale['402']),
                "outbox"  => array("link" => BASEDIR."messages.php?folder=outbox", "title" => $locale['403']),
                "archive" => array("link" => BASEDIR."messages.php?folder=archive", "title" => $locale['404']),
                "options" => array("link" => BASEDIR."messages.php?folder=options", "title" => $locale['425']),
            ),
            "inbox_total" => dbrows(dbquery("SELECT message_id FROM ".DB_MESSAGES." WHERE message_user='".$userdata['user_id']."' and message_to='".$userdata['user_id']."' AND message_folder='0'")),
            "outbox_total" => dbrows(dbquery("SELECT message_id FROM ".DB_MESSAGES." WHERE message_user='".$userdata['user_id']."' and message_to='".$userdata['user_id']."' AND message_folder='1'")),
            "archive_total" => dbrows(dbquery("SELECT message_id FROM ".DB_MESSAGES." WHERE message_user='".$userdata['user_id']."' and message_to='".$userdata['user_id']."' AND message_folder='2'")),
            "button" => array(
                "new" => array(
                    'link' => BASEDIR."messages.php?msg_send=new",
                    'name' => $locale['401']
                ),
                "options" => array('link' => BASEDIR."messages.php?folder=options", 'name' => $locale['425']),
            ),
            "actions_form" => "",
        );
        add_to_title($locale['global_200'].$locale['400']);
        add_to_meta("description", $locale['400']);
    }

    public static function get_pm_settings($user_id, $key = NULL) {
        if (iMEMBER) {
            global $userdata;
            // make sure they have it when registering
            $settings = array(
                "user_inbox" => fusion_get_settings("pm_inbox_limit"),
                "user_outbox" => fusion_get_settings("pm_outbox_limit"),
                "user_archive" => fusion_get_settings("pm_archive_limit"),
                "user_pm_email_notify" => fusion_get_settings("pm_email_notify"),
                "user_pm_save_sent" => fusion_get_settings("pm_save_sent"),
            );
            if ($user_id !== $userdata) {
                $result = dbquery("
				SELECT user_inbox, user_outbox, user_archive, user_pm_email_notify, user_pm_save_sent
				FROM ".DB_USERS." WHERE user_id='".intval($user_id)."' and user_status = '0'
				");
                if (dbrows($result) > 0) {
                    $data = dbarray($result);
                    // What this does is that if any of the params is 0, we use default system values.
                    $settings = array(
                        "user_inbox" => !empty($data['user_inbox']) ? intval($data['user_inbox']) : intval($settings['user_inbox']),
                        "user_outbox" => !empty($data['user_outbox']) ? intval($data['user_outbox']) : intval($settings['user_outbox']),
                        "user_archive" => !empty($data['user_archive']) ? intval($data['user_archive']) : intval($settings['user_archive']),
                        // 0 to use core. So core values must be 1 is no, 2 is yes.
                        "user_pm_email_notify" => !empty($data['user_pm_email_notify']) ? intval($data['user_pm_email_notify']) : intval($settings['user_pm_email_notify']),
                        "user_pm_save_sent" => !empty($data['user_pm_save_sent']) ? intval($data['user_pm_save_sent']) : intval($settings['user_pm_save_sent']),
                    );
                }
            } else {
                $settings = array(
                    "user_inbox" => $userdata['user_inbox'],
                    "user_outbox" => $userdata['user_outbox'],
                    "user_archive" => $userdata['user_archive'],
                    "user_pm_email_notify" => $userdata['user_pm_email_notify'],
                    "user_pm_save_sent" => $userdata['user_pm_save_sent']
                );
            }
            if (iADMIN || iSUPERADMIN) {
                $settings['user_inbox'] = 0;
                $settings['user_outbox'] = 0;
                $settings['user_archive'] = 0;
            }

            return $key === NULL ? $settings : (isset($settings[$key]) ? $settings[$key] : NULL);
        }

        return NULL;
    }

	/**
     * PM settings page
     */
    public function display_settings() {
        global $userdata, $locale;
        if (isset($_POST['save_options'])) {
            $data = array(
                "user_id" => $userdata['user_id'],
                "user_pm_email_notify" => form_sanitizer($_POST['pm_email_notify'], 0, "pm_email_notify"),
                "user_pm_save_sent" => form_sanitizer($_POST['pm_save_sent'], 0, "pm_save_sent"),
            );
            dbquery_insert(DB_USERS, $data, "update");
            addNotice("success", $locale['445']);
            redirect(BASEDIR."messages.php?folder=options");
        }
        ob_start();
        echo openform('pm_form', 'post', BASEDIR."messages.php?folder=".$_GET['folder']);
        $options = array(
            "0" => $locale['520'],
            "1" => $locale['521'],
            "2" => $locale['522'],
        );
        echo form_select('pm_email_notify', $locale['621'], $userdata['user_pm_email_notify'],
                         array("options" => $options));
        $options = array(
            "0" => $locale['520'],
            "1" => $locale['523'],
            "2" => $locale['524'],
        );
        echo form_select('pm_save_sent', $locale['622'], $userdata['user_pm_save_sent'], array("options" => $options));
        echo form_button('save_options', $locale['623'], $locale['623'], array("class" => "btn btn-primary"));
        echo closeform();
        $this->info['options_form'] = ob_get_contents();
        ob_end_clean();
    }

    /**
	 * Actions : archive
	 * Require - $_POST selectedPM, delete_pm
	 * SQL archive action

	 */
	private function archive_pm() {
		global $userdata, $locale;
		$messages = explode(",", rtrim(form_sanitizer($_POST['selectedPM'], "", "selectedPM"), ","));
		/**
		 * Method to count checkboxes during display
		 * as opposed to using selectedPM
		 * $check_count = 0;
		 * if (isset($_POST['check_mark'])) {
		 * if (is_array($_POST['check_mark']) && count($_POST['check_mark']) > 1) {
		 * foreach ($_POST['check_mark'] as $thisnum) {
		 * if (isnum($thisnum)) $msg_ids .= ($msg_ids ? "," : "").$thisnum;
		 * $check_count++;
		 * }
		 * } else {
		 * if (isnum($_POST['check_mark'][0])) $msg_ids = $_POST['check_mark'][0];
		 * $check_count = 1;
		 * }
		 * }
		 */
		if (!empty($messages)) {
			foreach ($messages as $message_id) {
				$ownership = isnum($message_id) && dbcount("(message_id)", DB_MESSAGES, "message_id='".intval($message_id)."' and message_user='".intval($userdata['user_id'])."'") ? TRUE : FALSE;
				$within_limit = self::get_pm_settings($userdata['user_id'], "user_archive") == "0" || (self::get_pm_settings($userdata['user_id'], "user_archive") > 0 && self::get_pm_settings($userdata['user_id'], "user_archive")-1 > $this->info['archive_total']) ? TRUE : FALSE;
				if ($ownership && $within_limit && isset($this->info['items'][$message_id])) {
					$moveData = $this->info['items'][$message_id];
					$moveData['message_folder'] = 2;
					dbquery_insert(DB_MESSAGES, $moveData, 'update');
				}
			}
			addNotice("success", $locale['489']);
			redirect(clean_request("", array("folder"), TRUE));
		}
	}

    // 9.0 new - send pm core functions -- add send to group using recursive statement.

	private function unarchive_pm() {
		global $userdata, $locale;
		$messages = explode(",", rtrim(form_sanitizer($_POST['selectedPM'], "", "selectedPM"), ","));
		if (!empty($messages)) {
			foreach ($messages as $message_id) {
				$ownership = isnum($message_id) && dbcount("(message_id)", DB_MESSAGES, "message_id='".intval($message_id)."' and message_user='".intval($userdata['user_id'])."'") ? TRUE : FALSE;
				$within_limit = self::get_pm_settings($userdata['user_id'], "user_inbox") == "0" || (self::get_pm_settings($userdata['user_id'], "user_inbox") > 0 && self::get_pm_settings($userdata['user_id'], "user_inbox")-1 > $this->info['inbox_total']) ? TRUE : FALSE;
				if ($ownership && $within_limit && isset($this->info['items'][$message_id])) {
					$moveData = $this->info['items'][$message_id];
					$moveData['message_folder'] = 0;
					dbquery_insert(DB_MESSAGES, $moveData, 'update');
				}
			}
			addNotice("success", $locale['489b']);
			redirect(clean_request("", array("folder"), TRUE));
		}
	}

	/**
	 * Actions: delete
	 * Require - $_POST selectedPM, delete_pm
	 * SQL delete message pm
	 */
	private function delete_pm() {
		global $userdata, $locale;
		$messages = explode(",", rtrim(form_sanitizer($_POST['selectedPM'], "", "selectedPM"), ","));
		if (!empty($messages)) {
			foreach ($messages as $message_id) {
				$ownership = isnum($message_id) && dbcount("(message_id)", DB_MESSAGES, "message_id='".intval($message_id)."' and message_user='".intval($userdata['user_id'])."'") ? TRUE : FALSE;
				if ($ownership && isset($this->info['items'][$message_id])) {
					$moveData = $this->info['items'][$message_id];
					dbquery_insert(DB_MESSAGES, $moveData, "delete");
				}
			}
			addNotice("success", $locale['490']);
			redirect(clean_request("", array("folder"), TRUE));
		}
	}

	/**
     * Actions : marking
     * Require - $_POST selectedPM, mark
     * SQL mark all, mark single (read or unread)
     */
    private function mark_pm() {
        global $userdata;
        switch (form_sanitizer($_POST['mark'], "")) {
            case "mark_all": // mark all as read
                if (!empty($this->info['items'])) {
                    foreach ($this->info['items'] as $message_id => $array) {
                        $ownership = isnum($message_id) && dbcount("(message_id)", DB_MESSAGES,
                                                                   "message_id='".intval($message_id)."' and message_user='".intval($userdata['user_id'])."'") ? TRUE : FALSE;
                        if ($ownership && isset($this->info['items'][$message_id])) {
                            dbquery("UPDATE ".DB_MESSAGES." SET message_read='1' WHERE message_id='".intval($message_id)."'");
                        }
                    }
                    redirect(clean_request("", array("folder"), TRUE));
                }
                break;
            case "unmark_all": // mark all as unread
                if (!empty($this->info['items'])) {
                    foreach ($this->info['items'] as $message_id => $pmData) {
                        $ownership = isnum($message_id) && dbcount("(message_id)", DB_MESSAGES,
                                                                   "message_id='".intval($message_id)."' and message_user='".intval($userdata['user_id'])."'") ? TRUE : FALSE;
                        if ($ownership && isset($this->info['items'][$message_id])) {
                            dbquery("UPDATE ".DB_MESSAGES." SET message_read='0' WHERE message_id='".intval($message_id)."'");
                        }
                    }
                    redirect(clean_request("", array("folder"), TRUE));
                }
                break;
            case "mark_read":
                $messages = explode(",", rtrim(form_sanitizer($_POST['selectedPM'], "", "selectedPM"), ","));
                if (!empty($messages)) {
                    foreach ($messages as $message_id) {
                        $ownership = isnum($message_id) && dbcount("(message_id)", DB_MESSAGES,
                                                                   "message_id='".intval($message_id)."' and message_user='".intval($userdata['user_id'])."'") ? TRUE : FALSE;
                        if ($ownership && isset($this->info['items'][$message_id])) {
                            dbquery("UPDATE ".DB_MESSAGES." SET message_read='1' WHERE message_id='".intval($message_id)."'");
                        }
                    }
                }
                redirect(clean_request("", array("folder"), TRUE));
                break;
            case "mark_unread":
                $messages = explode(",", rtrim(form_sanitizer($_POST['selectedPM'], "", "selectedPM"), ","));
                if (!empty($messages)) {
                    foreach ($messages as $message_id) {
                        $ownership = isnum($message_id) && dbcount("(message_id)", DB_MESSAGES,
                                                                   "message_id='".intval($message_id)."' and message_user='".intval($userdata['user_id'])."'") ? TRUE : FALSE;
                        if ($ownership && isset($this->info['items'][$message_id])) {
                            dbquery("UPDATE ".DB_MESSAGES." SET message_read='0' WHERE message_id='".intval($message_id)."'");
                        }
                    }
                }
                redirect(clean_request("", array("folder"), TRUE));
        }
    }

    // there are 5 parts in PM

    /**
	 * Reply and send
	 * SQL send pm
	 */
	private function send_message() {
        global $userdata, $locale, $defender;

		$inputData = array();
		if (iADMIN && isset($_POST['chk_sendtoall'])) {
			$inputData += array(
				"to_group" => isset($_POST['msg_group_send']) ? form_sanitizer($_POST['msg_group_send'], 0, 'msg_group_send') : 0,
			);
		} else {
            $inputData += array(
                "to" => form_sanitizer($_POST['msg_send'], 0, 'msg_send'),
            );
        }

		$inputData += array(
			"from" => $userdata['user_id'],
			"subject" => form_sanitizer($_POST['subject'], '', 'subject'),
			"message" => form_sanitizer($_POST['message'], '', 'message'),
			"smileys" => isset($_POST['chk_disablesmileys']) || preg_match("#(\[code\](.*?)\[/code\]|\[geshi=(.*?)\](.*?)\[/geshi\]|\[php\](.*?)\[/php\])#si", $_POST['message']) ? "n" : "y",
			"to_group" => 0
		);

        if ($defender::safe()) {

			if (iADMIN && isset($_POST['chk_sendtoall']) && $inputData['to_group']) {

                self::send_pm($inputData['to_group'], $inputData['from'], $inputData['subject'], $inputData['message'], $inputData['smileys'], TRUE);

			} else {

				self::send_pm($inputData['to'], $inputData['from'], $inputData['subject'], $inputData['message'], $inputData['smileys'], FALSE);

			}

            if (\defender::safe()) {

                addNotice("success", $locale['491']);

                redirect(BASEDIR."messages.php");

            }

		}
	}

	public static function send_pm($to, $from, $subject, $message, $smileys = 'y', $to_group = FALSE, $save_sent = TRUE) {

        include LOCALE.LOCALESET."messages.php";

        require_once INCLUDES."sendmail_include.php";

        require_once INCLUDES."flood_include.php";

        $strict = FALSE;

        $locale = array();

        $group_name = getgroupname($to);

		$to = isnum($to) || !empty($group_name) ? $to : 0;

		$from = isnum($from) ? $from : 0;

		$smileys = preg_match("#(\[code\](.*?)\[/code\]|\[geshi=(.*?)\](.*?)\[/geshi\]|\[php\](.*?)\[/php\])#si", $message) ? "n" : $smileys;

		if (!$to_group) {

			// send to user
			$pmStatus = self::get_pm_settings($to);
			$myStatus = self::get_pm_settings($from);

			if (!flood_control("message_datestamp", DB_MESSAGES, "message_from='".intval($from)."'")) {

				// find receipient
				$result = dbquery("SELECT u.user_id, u.user_name, u.user_email, u.user_level,
				COUNT(m.message_id) 'message_count'
				FROM ".DB_USERS." u
				LEFT JOIN ".DB_MESSAGES." m ON m.message_user=u.user_id and message_folder='0'
				WHERE u.user_id='".intval($to)."' GROUP BY u.user_id
				");

				if (dbrows($result) > 0) {
					$data = dbarray($result);
					$result2 = dbquery("SELECT user_id, user_name FROM ".DB_USERS." WHERE user_id='".intval($from)."'");
					if (dbrows($result2)>0) {
						$userdata = dbarray($result2);
						if ($to != $from) {
							if ($data['user_id'] == 1 // recepient is SA
								|| $data['user_level'] < USER_LEVEL_MEMBER || //recepient is Admin
								!$pmStatus['user_inbox'] || // have unlimited inbox
								($data['message_count']+1) <= $pmStatus['user_inbox'] // recepient inbox still within limit
							) {
								$inputData = array(
									"message_id" => 0,
									"message_to" => $to,
									"message_user" => $to,
									"message_from" => $from,
									"message_subject" => $subject,
									"message_message" => $message,
									"message_smileys" => $smileys,
									"message_read" => 0,
									"message_datestamp" => time(),
									"message_folder" => 0,
								);
								dbquery_insert(DB_MESSAGES, $inputData, "save");

								// this will flood the inbox when message is sent to group. -- fixed
                                if ($myStatus['user_pm_save_sent'] == '2' && $save_sent == TRUE) {
									// user_outbox.
									$cdata = dbarray(dbquery("SELECT COUNT(message_id) AS outbox_count, MIN(message_id) AS last_message FROM
									".DB_MESSAGES." WHERE message_to='".$userdata['user_id']."' AND message_user='".$userdata['user_id']."' AND message_folder='1' GROUP BY message_to"));
									// check my outbox limit and if surpass, remove oldest message
									if ($myStatus['user_outbox'] !="0" && ($cdata['outbox_count'] + 1) > $myStatus['user_outbox']) {
										dbquery("DELETE FROM ".DB_MESSAGES." WHERE message_id='".$cdata['last_message']."' AND message_to='".$userdata['user_id']."'");
									}
									$inputData['message_user'] = $userdata['user_id'];
									$inputData['message_folder'] = 1;
									$inputData['message_from'] = $to;
									$inputData['message_to'] = $userdata['user_id'];
									dbquery_insert(DB_MESSAGES, $inputData, "save");
								}

								$send_email = $pmStatus['user_pm_email_notify'];

								if ($send_email == "2") {
									$message_content = str_replace("[SUBJECT]", $subject, $locale['626']);
									$message_content = str_replace("[USER]", $userdata['user_name'], $message_content);
									$template_result = dbquery("SELECT template_key, template_active FROM ".DB_EMAIL_TEMPLATES." WHERE template_key='PM' LIMIT 1");
									if (dbrows($template_result)) {
										$template_data = dbarray($template_result);
										if ($template_data['template_active'] == "1") {
											sendemail_template("PM", $subject, trimlink($message, 150), $userdata['user_name'], $data['user_name'], "", $data['user_email']);
										} else {
											sendemail($data['user_name'], $data['user_email'], fusion_get_settings("siteusername"), fusion_get_settings("siteemail"), $locale['625'], $data['user_name'].$message_content);
										}
									} else {
										sendemail($data['user_name'], $data['user_email'], fusion_get_settings("siteusername"), fusion_get_settings("siteemail"), $locale['625'], $data['user_name'].$message_content);
									}
								}
							} else {
								// Inbox is full
								if ($strict) die("User inbox is full. Try delete it or upgrade it to 102 or 103 status");

                                \defender::stop();
								addNotice("danger", $locale['628']);
							}
						}

					} else {
						// Sender does not exist in DB
						if ($strict) die("Sender User ID does not exist in DB. Sequence Aborted.");
                        \defender::stop();
						addNotice("danger", $locale['482']);
					}

				} else {

                    \defender::stop();
                    if ($strict) die("Message Recepient User ID is invalid");
					addNotice("danger", $locale['482']);

				}

			} else {

				if ($strict) die("You are flooding, send_pm halted");
                \defender::stop();
				addNotice("danger", sprintf($locale['487'], fusion_get_settings("flood_interval")));

			}

		} else {

			$result = NULL;
			if ($to <= -101 && $to >= -103) { // -101, -102, -103 only
				$result = dbquery("SELECT user_id from ".DB_USERS." WHERE user_level <='".intval($to)."' AND user_status='0'");
			} else {
                // ## --- deprecate -- WHERE user_groups REGEXP('^\\\.{$to}$|\\\.{$to}\\\.|\\\.{$to}$') #
				$result = dbquery("SELECT user_id FROM ".DB_USERS." WHERE ".in_group("user_groups", $to)." AND user_status='0'");
			}
			if (dbrows($result) > 0) {

                while ($data = dbarray($result)) {
					self::send_pm($data['user_id'], $from, $subject, $message, $smileys, FALSE, FALSE);
				}

			} else {
                \defender::stop();
                addNotice("danger", $locale['492']);
			}
		}
	}

	/**
	 * Private message forms
	 * pm_form (Short form)
	 * pm_mainForm (Full composing environment)
	 */
	public function pm_form() {
		global $locale;
		$this->info['button'] += array(
			"back" => array("link" => BASEDIR."messages.php?folder=".$_GET['folder'], "title" => $locale['back']),
		);
        $this->info['reply_form'] = openform('inputform', 'post',
                                             BASEDIR."messages.php?folder=".$_GET['folder']."&amp;msg_read=".$_GET['msg_read'])
									.form_hidden("msg_send", "", $this->info['items'][$_GET['msg_read']]['message_from'])
									.form_hidden("subject", "", $this->info['items'][$_GET['msg_read']]['message_subject'])
									.form_textarea("message", $locale['422'], '', array(
					'required' => TRUE,
					'autosize' => TRUE,
					'no_resize' => 0,
					'preview' => TRUE,
					'form_name' => 'inputform',
					'bbcode' => TRUE
				)).form_button('cancel', $locale['cancel'], $locale['cancel']).form_button('send_message', $locale['430'], $locale['430'], array(
					'class' => 'btn m-l-10 btn-primary'
				)).closeform();
	}

	/**
	 * New message form
	 */
	public function pm_mainForm() {
		global $locale;

        $_GET['msg_send'] = isset($_GET['msg_send']) ? $_GET['msg_send'] : "";

		if (iADMIN) {
			$input_header = "<a class='pull-right m-b-10 display-inline-block' id='mass_send'>".$locale['434']."</a><br/>";
			$input_header .= form_user_select("msg_send", $locale['420a'], $_GET['msg_send'], array(
				"required" => TRUE,
				"inline" => TRUE,
				'placeholder' => $locale['421']
			));
			$input_header .= "<div id='msg_to_group-field' class='form-group display-none'>\n";
			$input_header .= "<label for='mg_to_group' class='control-label col-xs-12 col-sm-3 col-md-3 col-lg-3 p-l-0'>".$locale['434']."
								<input id='all_check' name='chk_sendtoall' type='checkbox' class='pull-left display-inline-block'
							   style='margin-right:10px !important;'/></label>\n";
			$input_header .= "<div class='col-xs-12 col-sm-9 col-md-9 col-lg-9'>\n";
			$user_groups = fusion_get_groups();
			unset($user_groups[0]);
			$input_header .= form_select('msg_group_send', "", "", array(
				'options' => $user_groups,
				'width' => "100%",
				'class' => 'm-b-0'
			));
			$input_header .= "</div>\n</div>\n";
			// Toggle "Send to All" link
			add_to_jquery("
				$('#mass_send').bind('click', function() {
				$('#msg_to_group-field').toggleClass('display-none');
				$('#msg_send-field').toggleClass('display-none');
				var invisible = $('#msg_to_group-field').hasClass('display-none');
				if (invisible) {
					$('#all_check').prop('checked', false);
				} else {
					$('#all_check').prop('checked', true);
				}
				});
				");
		} else {
            $input_header = form_user_select("msg_send", $locale['420a'], $_GET['msg_send'], array(
				"required" => TRUE,
				'input_id' => 'msgsend2',
				"inline" => TRUE,
				'placeholder' => $locale['421']
			));
        }
        $this->info['reply_form'] = openform('inputform', 'post',
                                             BASEDIR."messages.php?folder=".$_GET['folder']."&amp;msg_send=".$_GET['msg_send'])
									.$input_header.form_text('subject', $locale['405'], '', array(
				"required" => TRUE,
				"inline" => TRUE,
				'max_length' => 100,
				"autocomplete_off" => TRUE,
				"width" => "100%",
				'placeholder' => $locale['405']
			)).form_textarea('message', $locale['422'], '', array(
				"required" => TRUE,
				'error_text' => '',
				'autosize' => 1,
				'no_resize' => 0,
				'preview' => 1,
				'form_name' => 'inputform',
				"height" => "150px",
				'bbcode' => 1
			)).form_button('cancel', $locale['cancel'], $locale['cancel']).form_button('send_pm', $locale['430'], $locale['430'], array(
				'class' => 'btn m-l-10 btn-primary'
			)).closeform();
	}
}