<?php

/*
ET-Chat Copyright by SEDesign | ET-Chat v3.x.x Lizenz: CCPL | Autor: Evgeni Tcherkasski (info@s-e-d.de)
ET-Chat_T-FISH-MOD Weiterentwicklungen, Optimierungen und Ergänzungen am Code sind das geistige Eigentum von Tommy (Thomas Kuhn) und Harlekin (Bernd Witte).

Die darauf folgende Optimierungen und Ergänzungen am Code sind das Geistige Eigentum von Powermen (Christian K.) 
PHP 8/9 Ready, XML Parser, PDO Prepared Statements Get Set sicherheit usw.
*/

class ReloaderMessages extends DbConectionMaker
{
    public function __construct()
    {
        parent::__construct();

        if (session_status() === PHP_SESSION_NONE) {
            session_start();
        }

        if (!isset($_SESSION['etchat_'.$this->_prefix.'user_id'])) {
            die(json_encode(["error" => "Session user_id nicht gesetzt"]));
        }

        header('Cache-Control: no-store, no-cache, must-revalidate, pre-check=0, post-check=0, max-age=0');
        header('content-type: application/json; charset=utf-8');

        if ($this->checkKicklist()) {
            $this->errorOutput("kick");
            return false;
        }

        $blackListObj = new Blacklist($this->dbObj);

        if ($blackListObj->userInBlacklist()) {
            if ($blackListObj->allowedToAndSetCookie()) {
                $blackListObj->killUserSession();
                $this->errorOutput("blacklist");
                return false;
            }
        }

        $raum_array = $this->getRoomArray();
        if (!is_array($raum_array)) return false;

        $user_id = (int)($_SESSION['etchat_'.$this->_prefix.'user_id'] ?? 0);

        if ($user_id === 0) {
            die(json_encode(["error" => "Ungültige User-ID"]));
        }

        $user_array = $this->dbObj->sqlGet(
            "SELECT etchat_user_id, etchat_username, etchat_userprivilegien,
                    etchat_usersex, etchat_avatar
             FROM {$this->_prefix}etchat_user
             WHERE etchat_user_id = ?",
            [$user_id]
        );

        $this->refreshUserSession($user_array, $raum_array, $blackListObj->user_param_all);

        $_POST['privat'] = (int)($_POST['privat'] ?? 0);

        if (isset($_POST['message']) && !empty($_POST['message']) &&
            trim($_POST['message']) !== "/window:" &&
            !empty($_SESSION['etchat_'.$this->_prefix.'user_id'])) {

            $inserterObj = new MessageInserter($this->dbObj, $raum_array);

            if (!empty($inserterObj->status)) {
                $this->errorOutput($inserterObj->status);
                return false;
            }
        }

        $this->makeJsonOutput($this->selectMessagesForTheUser());
    }

    private function makeJsonOutput($feld)
    {
        $ausgabeJSON_Inhalt = [];

        static $sml = null;

			if ($sml === null) {
				$sml = $this->dbObj->sqlGet(
					"SELECT etchat_smileys_sign, etchat_smileys_img FROM {$this->_prefix}etchat_smileys"
				) ?: [];
			}

        if (!empty($feld) && is_array($feld)) {
            $ausgabeJSON_Anfang = "{\"data\" : [";

            foreach ($feld as $row) {

				if (!$this->blockiere($row[6], $row[5])) {

					$message2send = addslashes(
						StaticMethods::filtering(stripslashes($row[2]), $sml, $this->_prefix)
					);

					if (substr($message2send, 0, 8) === "/window:" && $row[5] != 0) {
						$message2send = substr($message2send, 8);
						$normal_message_counter = "";
					} else {
						$_SESSION['etchat_'.$this->_prefix.'count'] ??= 0;
						$_SESSION['etchat_'.$this->_prefix.'count']++;
						$normal_message_counter = $_SESSION['etchat_'.$this->_prefix.'count'];
					}

					$ausgabeJSON_Inhalt[] = "{\"id\":\"".$normal_message_counter.
						"\",\"user\":\"".addslashes($row[1]).
						"\",\"user_id\":\"".addslashes($row[6]).
						"\",\"message\":\"".$message2send.
						"\",\"time\":\"".date("H:i", $row[3]).
						"\",\"privat\":\"".$row[5].
						"\",\"css\":\"".$row[7].
						"\",\"priv\":\"".$row[8].
						"\",\"sex\":\"".$row[9].
						"\",\"avatar\":\"".$row[10]."\"}";
				}
			}

            $ausgabeJSON_Ende = "]}";
        }

        $this->dbObj->close();

        if (count($ausgabeJSON_Inhalt) > 0) {
			echo $ausgabeJSON_Anfang . implode(",", $ausgabeJSON_Inhalt) . $ausgabeJSON_Ende;
		} else {
			echo '{"data":[]}';
		}
    }

    private function refreshUserSession($user_array, $raum_array, $user_param_all)
    {
        $user_onlineid = $this->dbObj->sqlGet(
            "SELECT etchat_onlineid
             FROM {$this->_prefix}etchat_useronline
             WHERE etchat_onlineuser_fid = ?",
            [$_SESSION['etchat_'.$this->_prefix.'user_id']]
        );

        if (is_array($user_onlineid)) {

            $this->dbObj->sqlSet(
                "UPDATE {$this->_prefix}etchat_useronline SET
                    etchat_onlineuser_fid = ?,
                    etchat_onlinetimestamp = ?,
                    etchat_onlineip = ?,
                    etchat_fid_room = ?,
                    etchat_user_online_room_goup = ?,
                    etchat_user_online_room_name = ?,
                    etchat_user_online_user_name = ?,
                    etchat_user_online_user_priv = ?,
                    etchat_user_online_user_sex = ?,
                    etchat_avatar = ?
                 WHERE etchat_onlineid = ?",
                [
                    $user_array[0][0],
                    time(),
                    $user_param_all,
                    $raum_array[0][0],
                    $raum_array[0][2],
                    $raum_array[0][1],
                    $user_array[0][1],
                    $user_array[0][2],
                    $user_array[0][3],
                    $user_array[0][4],
                    $user_onlineid[0][0]
                ]
            );

        } else {

            $this->dbObj->sqlSet(
                "INSERT INTO {$this->_prefix}etchat_useronline (
                    etchat_onlineuser_fid,
                    etchat_onlinetimestamp,
                    etchat_onlineip,
                    etchat_fid_room,
                    etchat_user_online_room_goup,
                    etchat_user_online_room_name,
                    etchat_user_online_user_name,
                    etchat_user_online_user_priv,
                    etchat_user_online_user_sex,
                    etchat_logintime
                ) VALUES (?,?,?,?,?,?,?,?,?,?)",
                [
                    $user_array[0][0],
                    time(),
                    $user_param_all,
                    $raum_array[0][0],
                    $raum_array[0][2],
                    $raum_array[0][1],
                    $user_array[0][1],
                    $user_array[0][2],
                    $user_array[0][3],
                    time()
                ]
            );

            if (!empty($_SESSION['etchat_'.$this->_prefix.'invisible_on_enter'])) {
                $this->dbObj->sqlSet(
                    "UPDATE {$this->_prefix}etchat_useronline
                     SET etchat_user_online_user_status_img = 'status_invisible',
                         etchat_user_online_user_status_text = ''
                     WHERE etchat_onlineuser_fid = ?",
                    [$_SESSION['etchat_'.$this->_prefix.'user_id']]
                );
            }
        }
    }

    private function getRoomArray()
    {
        $raum_array = $this->dbObj->sqlGet(
            "SELECT etchat_id_room, etchat_roomname, etchat_room_goup, etchat_room_message
             FROM {$this->_prefix}etchat_rooms
             WHERE etchat_id_room = ?",
            [(int)($_POST['room'] ?? 0)]
        );

        if (!is_array($raum_array) || empty($raum_array)) {
            $_POST['room'] = 1;

            $raum_array = $this->dbObj->sqlGet(
                "SELECT etchat_id_room, etchat_roomname, etchat_room_goup
                 FROM {$this->_prefix}etchat_rooms
                 WHERE etchat_id_room = 1"
            );
        }
        else {
            $room_allowed = new RoomAllowed($raum_array[0][2], $raum_array[0][0]);

            if ($room_allowed->room_status != 1) {
                $_POST['room'] = 1;
                unset($_POST['message']);

                $raum_array = $this->dbObj->sqlGet(
                    "SELECT etchat_id_room, etchat_roomname, etchat_room_goup
                     FROM {$this->_prefix}etchat_rooms
                     WHERE etchat_id_room = 1"
                );
            }
        }

        return $raum_array;
    }

    private function checkKicklist()
    {
        $kicklist = $this->dbObj->sqlGet(
            "SELECT id FROM {$this->_prefix}etchat_kick_user
             WHERE etchat_kicked_user_id = ?",
            [$_SESSION['etchat_'.$this->_prefix.'user_id']]
        );

        if (is_array($kicklist)) {

            $this->dbObj->sqlSet(
                "DELETE FROM {$this->_prefix}etchat_kick_user
                 WHERE etchat_kicked_user_id = ?",
                [$_SESSION['etchat_'.$this->_prefix.'user_id']]
            );

            $rechte_zum_kicken = $this->dbObj->sqlGet(
                "SELECT etchat_userprivilegien
                 FROM {$this->_prefix}etchat_user
                 WHERE etchat_user_id = ?",
                [$_SESSION['etchat_'.$this->_prefix.'user_id']]
            );

            if ($rechte_zum_kicken[0][0] !== "admin" && $rechte_zum_kicken[0][0] !== "mod") {
                return true;
            }

            return false;
        }

        return false;
    }

    private function errorOutput($message = 0)
    {
        echo $message;
        $this->dbObj->close();
    }

    private function selectMessagesForTheUser()
    {
        $where_sys_messages = '';

        if (empty($_SESSION['etchat_'.$this->_prefix.'last_id'])) {

            if (isset($_SESSION['etchat_'.$this->_prefix.'sys_messages']) &&
                !$_SESSION['etchat_'.$this->_prefix.'sys_messages']) {

                $where_sys_messages = "(etchat_user_fid<>1 or (etchat_user_fid=1 and etchat_privat=?)) and ";
                $this->_messages_shown_on_entrance--;
            }

            $counted_ids = $this->dbObj->sqlGet(
                "SELECT count(etchat_id)
                 FROM {$this->_prefix}etchat_messages
                 WHERE etchat_id > ?
                 AND etchat_fid_room IN (?,0)
                 AND (etchat_privat = 0 OR etchat_privat = ?)",
                [
                    $_SESSION['etchat_'.$this->_prefix.'my_first_mess_id'],
                    (int)($_POST['room'] ?? 0),
                    $_SESSION['etchat_'.$this->_prefix.'user_id']
                ]
            );

            if (is_array($counted_ids) && $counted_ids[0][0] >= $this->_messages_shown_on_entrance) {
                $this->_messages_shown_on_entrance += $counted_ids[0][0];
            }

            $feld = $this->dbObj->sqlGet(
                "SELECT etchat_id, etchat_username, etchat_text, etchat_timestamp,
                        etchat_fid_room, etchat_privat, etchat_user_id,
                        etchat_text_css, etchat_userprivilegien, etchat_usersex,
                        etchat_avatar
                 FROM {$this->_prefix}etchat_messages
                 JOIN {$this->_prefix}etchat_user
                   ON etchat_user_id = etchat_user_fid
                 WHERE (etchat_fid_room IN (?,0) OR etchat_privat = ?)
                   AND ".$where_sys_messages."
                   (etchat_privat = 0 OR etchat_privat = ? OR etchat_user_fid = ?)
                 ORDER BY etchat_id DESC
                 LIMIT ?",
                [
                    (int)($_POST['room'] ?? 0),
                    $_SESSION['etchat_'.$this->_prefix.'user_id'],
                    $_SESSION['etchat_'.$this->_prefix.'user_id'],
                    $_SESSION['etchat_'.$this->_prefix.'user_id'],
                    $this->_messages_shown_on_entrance
                ]
            );

            $_SESSION['etchat_'.$this->_prefix.'last_id'] = ($feld && isset($feld[0][0]))
                ? $feld[0][0]
                : 0;

            $feld = array_reverse($feld);
        }
        else {

            if (isset($_SESSION['etchat_'.$this->_prefix.'sys_messages']) &&
                !$_SESSION['etchat_'.$this->_prefix.'sys_messages']) {

                $where_sys_messages = "(etchat_user_fid<>1 or (etchat_user_fid=1 and etchat_privat=?)) and ";
            }

            $feld = $this->dbObj->sqlGet(
                "SELECT etchat_id, etchat_username, etchat_text, etchat_timestamp,
                        etchat_fid_room, etchat_privat, etchat_user_id,
                        etchat_text_css, etchat_userprivilegien, etchat_usersex,
                        etchat_avatar
                 FROM {$this->_prefix}etchat_messages
                 JOIN {$this->_prefix}etchat_user
                   ON etchat_user_id = etchat_user_fid
                 WHERE (etchat_fid_room IN (?,0) OR etchat_privat = ?)
                   AND etchat_id > ?
                   AND ".$where_sys_messages."
                   (etchat_privat = 0 OR etchat_privat = ? OR etchat_user_fid = ?)
                 ORDER BY etchat_id",
                [
                    (int)($_POST['room'] ?? 0),
                    $_SESSION['etchat_'.$this->_prefix.'user_id'],
                    $_SESSION['etchat_'.$this->_prefix.'last_id'],
                    $_SESSION['etchat_'.$this->_prefix.'user_id'],
                    $_SESSION['etchat_'.$this->_prefix.'user_id']
                ]
            );

            $_SESSION['etchat_'.$this->_prefix.'last_id'] =
                ($feld && count($feld) > 0) ? $feld[count($feld)-1][0] : $_SESSION['etchat_'.$this->_prefix.'last_id'];
        }

        return $feld;
    }

    private function blockiere($user_id, $privat_id)
    {
        if (isset($_SESSION['etchat_'.$this->_prefix.'block_all']) &&
            is_array($_SESSION['etchat_'.$this->_prefix.'block_all']) &&
            in_array($user_id, $_SESSION['etchat_'.$this->_prefix.'block_all'])) {
            return true;
        }

        if (isset($_SESSION['etchat_'.$this->_prefix.'block_priv']) &&
            is_array($_SESSION['etchat_'.$this->_prefix.'block_priv']) &&
            in_array($user_id, $_SESSION['etchat_'.$this->_prefix.'block_priv']) &&
            $privat_id == $_SESSION['etchat_'.$this->_prefix.'user_id']) {
            return true;
        }

        return false;
    }
}