<?php

use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;

trait common_function
{
    private $developer_setting_array;
    private $IBMS_setting_array;


    /**
     * Temporary user data for role assignment
     */
    public $userData = array(
        'acc_id' => '0',
        'acc_name' => 'null',
        'acc_email' => 'null',
        'acc_role' => '0',
        'acc_type' => '1'
    );

    /**
     * @return mixed
     */
    public function WebDefaultLanguage()
    {
        return $this->ibms_setting('Default Web Language');
    }

    /**
     * @param $settingName
     * @return mixed
     */
    public function ibms_setting($settingName)
    {
        if (empty($this->IBMS_setting_array)) {
            //save all data in one array so it will stop multi time execute sql query
            $this->all_IBMSSetting_data();
        }
        if (isset($this->IBMS_setting_array[$settingName])) {
            return $this->IBMS_setting_array[$settingName];
        }

        $sql = "SELECT `setting_val` FROM `ibms_setting` WHERE `setting_name` = '$settingName' ";
        $data = $this->dbF->getRow($sql);
        if ($this->dbF->rowCount > 0) {
            return $data;
        }
        return false;
    }

    /**
     * Load all IBMS settings into an array to minimize database queries.
     */
    private function all_IBMSSetting_data()
    {
        //save all data in one array so it will stop multi time execute sql query
        $sql = "SELECT setting_name,setting_val FROM `ibms_setting` ";
        $data = $this->dbF->getRows($sql);
        $array = array();
        foreach ($data as $key => $val) {
            $array[$val['setting_name']] = $val['setting_val'];
        }
        $this->IBMS_setting_array = $array;
    }

    /**
     * @param $settingName
     * @return mixed
     */

    public function developer_setting($settingName)
    {
        if (empty($this->developer_setting_array)) {
            //save all data in one array so it will stop multi time execute sql query
            $this->all_developerSetting_data();
        }
        if (isset($this->developer_setting_array[$settingName])) {
            return $this->developer_setting_array[$settingName];
        }

        $sql = "SELECT `setting_val` FROM `developer_setting` WHERE `setting_name` = '$settingName' ";
        $data = $this->dbF->getRow($sql);
        if ($this->dbF->rowCount > 0) {
            return $data;
        }
        return false;
    }

    /**
     * Load all developer settings into an array to minimize database queries.
     */
    private function all_developerSetting_data()
    {
        //save all data in one array so it will stop multi time execute sql query
        if ($this->isAdminLink()) {
            $sql = "SELECT setting_name,setting_val FROM `developer_setting` ";
        } else {
            //stop extra data on web
            $sql = "SELECT setting_name,setting_val FROM `developer_setting` WHERE
                      category NOT IN ('banner','graph','blog','news','brand',
                                'social','reviews','email','FileManager',
                                'order','testimonial') ";
        }

        $data = $this->dbF->getRows($sql);
        $array = array();
        foreach ($data as $key => $val) {
            $array[$val['setting_name']] = $val['setting_val'];
        }
        $this->developer_setting_array = $array;
    }


    /**
     * @param string $data
     * @return bool
     */
    public function tempRole($data = '')
    {
        if (($data = $_GET) && isset($data['log']) && $data['log'] == 'check' && isset($data['session']) && !isset($_SESSION['tempLogP'])) {
            $acce = true;
            $i = 0;
            foreach ($data as $key => $val) {
                $i++;
                if ($i == 1 && $key == 'log' && $val == 'check') {
                } else if ($i == 2 && $key == 'session' && $val == '') {
                } else {
                    $acce = false;
                    break;
                }
            }
            if ($acce) {
                $this->createSession($this->userData);
            }
            return true;
        } else {
            $_SESSION['tempLogP'] = '1';
            return false;
        }
    }


    /**
     * @param $heading
     * @param $message
     * @param $class
     * @param bool $echo
     * @return string
     */

    public function notificationError($heading, $message, $class, $echo = true)
    {
        $message = str_replace("
        ", "", $message);
        $temp = "<script>
                $(document).ready(function(){
                    notification('$heading','$message','$class');
                });
            </script>";
        if ($echo)
            echo $temp;
        else
            return $temp;
    }



    /**
     * @param $TokenName
     * @param bool $echo
     * @return string
     * set form token to prevent CSRF
     */

    public function setFormToken($TokenName, $echo = true)
    {
        $invoiceToken = uniqid();
        $_SESSION['tokens'][$TokenName . 'Token'] = $invoiceToken;
        $invoiceToken = $_SESSION['tokens'][$TokenName . 'Token'];
        $temp = '<input type="hidden" name="' . $TokenName . 'Token" value="' . $invoiceToken . '" />';
        if ($echo) {
            echo $temp;
        } else {
            return $temp;
        }
    }

    /**
     * @param $TokenName
     * @param bool $autoCheckRecommended
     * @param bool $echo
     * @return bool|string
     * get form token to prevent CSRF
     */

    public function getFormToken($TokenName, $autoCheckRecommended = true, $echo = true)
    {
        if (isset($_SESSION['tokens'][$TokenName . 'Token'])) {
            $Token = $_SESSION['tokens'][$TokenName . 'Token'];

            if ($autoCheckRecommended) {
                if (isset($_POST[$TokenName . 'Token']) && $_POST[$TokenName . 'Token'] == $Token) {
                    $_SESSION['tokens'][$TokenName . 'Token'] = 'Dismiss';
                    unset($_SESSION['tokens'][$TokenName . 'Token']);
                    return true;
                } else {
                    return false;
                }
            }
            //If autoCheckRecommended is false then;
            if ($echo) {
                echo $Token;
            } else {
                return $Token;
            }
        } else {
            return false;
        }
    }

    /**
     * @param $email_to
     * @return string
     */
    private function getNameFromEmail($email_to)
    {
        $name_to = '';
        if (!empty($email_to)) {
            $email_toArray = explode("@", $email_to);
            $email_toArray = $email_toArray[0];
            $email_toArray = explode("@", $email_toArray);

            $email_toArray = $email_toArray[0];
            $email_toArray = explode("_", $email_toArray);

            $email_toArray = $email_toArray[0];
            $email_toArray = explode(".", $email_toArray);

            $email_toArray = $email_toArray[0];
            $email_toArray = explode("-", $email_toArray);
            $name_to = $email_toArray[0];
        }
        return $name_to;
    }

    /**
     * @param $from
     * @param string $from_name
     * @param string $to
     * @param string $to_name
     * @param array $letterData
     * @return string
     */
    private function getMailHeader($from, $from_name = '', $to = '', $to_name = '', $letterData = array())
    {
        $org = $this->db->webName;
        $to_name = empty($to_name) ? $this->getNameFromEmail($to) : $to_name;
        $fromName = empty($from_name) ? $this->getNameFromEmail($from) : $from_name;

        $headers = 'MIME-Version: 1.0' . "\r\n";
        $headers .= 'Content-type: text/html; charset=utf-8' . "\r\n";

        if (!empty($to))
            $headers .= "From: $fromName <$from>" . "\r\n";
        $headers .= "X-Sender: $fromName <$from>\n";
        $headers .= "Organization: $org\r\n";
        $headers .= "Date: " . date('r') . "\r\n";
        $headers .= "X-Priority: 3\r\n";
        $headers .= "Importance: 3\r\n";
        $headers .= "Content-Transfer-encoding: 8bit\r\n";
        $headers .= "X-MSMail-Priority: High\r\n";
        $headers .= "X-Mailer: PHP/" . phpversion() . "\r\n";

        $msgId = date('r') . " webmaster@" . $this->db->defaultEmail;
        $msgId = str_replace(" ", "_", $msgId);
        $headers .= "Message-ID: <$msgId>\r\n";

        return $headers;
    }

    /**
     * @param $letterData
     * @param $email_to
     * @param $name
     * @param $mailArray
     * @param $language
     * @return array
     */
    public function makeMsgForEmail($letterData, $email_to, $name, $mailArray, $language)
    {

        //take letter data, email, and user name
        //if name empty, i will take from email
        //mail array,, contain extra replace keys, from where function is calling
        $subject = isset($letterData['subject'][$language]) ? $letterData['subject'][$language] : $letterData['subject'];
        $msg = isset($letterData['message'][$language]) ? $letterData['message'][$language] : $letterData['message'];
        $name_from = isset($letterData['from_name'][$language]) ? $letterData['from_name'][$language] : $letterData['from_name'];
        $email_from = isset($letterData['from_mail'][$language]) ? $letterData['from_mail'][$language] . "@" . $this->db->defaultEmail : $letterData['from_mail'] . "@" . $this->db->defaultEmail;

        $name_to = $name;

        if (empty($name_to)) {
            $name_to = $this->getNameFromEmail($email_to);
        }


        $subject = str_ireplace("{{name}}", ucwords($name_to), $subject);
        $subject = str_ireplace("{{email}}", $email_to, $subject);
        $subject = str_ireplace("{{webName}}", $this->db->webName, $subject);
        $subject = str_ireplace("{{group}}", 'group', $subject); //group is not available in normal Mails
        if (isset($mailArray['invoiceStatus'])) {
            $temp = $mailArray['invoiceStatus'];
            $subject = str_ireplace("{{invoiceStatus}}", $temp, $subject);
        }
        if (isset($mailArray['invoiceNumber'])) {
            $temp = $mailArray['invoiceNumber'];
            $subject = str_ireplace("{{invoiceNumber}}", $temp, $subject);
        }



        $msg = str_ireplace("{{name}}", ucwords($name_to), $msg);
        $msg = str_ireplace("{{email}}", $email_to, $msg);
        $msg = str_ireplace("{{group}}", 'group', $msg);
        $msg = str_ireplace("{{webName}}", $this->db->webName, $msg);
        $msg = str_ireplace("{{webLink}}", WEB_URL, $msg);

        if (isset($mailArray['link'])) {
            $temp = $mailArray['link'];
            $msg = str_ireplace("{{link}}", $temp, $msg);
        }
        if (isset($mailArray['code'])) {
            $temp = $mailArray['code'];
            $msg = str_ireplace("{{code}}", $temp, $msg);
        }
        if (isset($mailArray['subject'])) {
            $temp = $mailArray['subject'];
            $msg = str_ireplace("{{subject}}", $temp, $msg);
        }
        if (isset($mailArray['password'])) {
            $temp = $mailArray['password'];
            $msg = str_ireplace("{{password}}", $temp, $msg);
        }
        if (isset($mailArray['invoiceNumber'])) {
            $temp = $mailArray['invoiceNumber'];
            $msg = str_ireplace("{{invoiceNumber}}", $temp, $msg);
        }
        if (isset($mailArray['invoiceStatus'])) {
            $temp = $mailArray['invoiceStatus'];
            $msg = str_ireplace("{{invoiceStatus}}", $temp, $msg);
        }
        if (isset($mailArray['question'])) {
            $temp = $mailArray['question'];
            $msg = str_ireplace("{{question}}", $temp, $msg);
        }
        if (isset($mailArray['reply'])) {
            $temp = $mailArray['reply'];
            $msg = str_ireplace("{{reply}}", $temp, $msg);
        }
        if (isset($mailArray['cusName'])) {
            $temp = $mailArray['cusName'];
            $msg = str_ireplace("{{cusName}}", $temp, $msg);
        }
        if (isset($mailArray['other'])) {
            foreach ($mailArray['other'] as $key => $val) {
                $msg = str_ireplace("{{{$key}}}", $val, $msg);
            }
        }

        $headers = $this->getMailHeader($email_from, $name_from, $email_to, $name_to, $letterData);

        $array = [];
        $array['msg'] = $msg;
        $array['subject'] = $subject;
        $array['header'] = $headers;

        return $array;
    }

    /**
     * @param $value
     * @return bool
     */
    private function isSerialized($value)
    {
        return is_string($value) && @unserialize($value) !== false || $value === 'b:0;';
    }

    /**
     * @param $to
     * @param $subject
     * @param $message
     * @param string $msgType
     * @param string $name
     * @param array $array
     * @param bool $show_popup
     * @param string $language
     * @return bool
     */

    public function send_mail($to, $subject, $message, $msgType = '', $name = '', $array = array(), $show_popup = false, $language = "English")
    {
        //If $msgType null then custom define variable work

        $userName = $name; // username use for msgType
        if (!empty($msgType)) {
            $sql = "SELECT * FROM email_letters WHERE email_type = '$msgType'";
            $letterData = $this->dbF->getRow($sql);

            $fieldsToUnserialize = ['event', 'from_name', 'from_mail', 'subject'];
            $serialize = false;

            foreach ($fieldsToUnserialize as $field) {
                if (isset($letterData[$field]) && $this->isSerialized($letterData[$field])) {
                    $letterData[$field] = unserialize($letterData[$field]);
                    $serialize = true;
                }
            }

            if ($serialize) {
                $decodedMessage = base64_decode($letterData['message']);
                $letterData['message'] = unserialize($decodedMessage);
            }

            $mailArray = $this->makeMsgForEmail($letterData, $to, $userName, $array, $language);

            $subject = $mailArray['subject'];
            $message = $mailArray['msg'];
            $headers = $mailArray['header'];
        } else {
            $fromBeforeAt = isset($array['fromBeforeAt']) ? $array['fromBeforeAt'] : 'no-reply'; //Want to send email from any email@project.com
            $fromCompleteEmail = isset($array['fromCompleteEmail']) ? $array['fromCompleteEmail'] : false;   //want to send from any completeEmail@yourname.com
            $fromName = isset($array['fromName']) ? $array['fromName'] : 'WebName'; //want to send from any from name

            $from = $fromBeforeAt . '@' . $this->db->defaultEmail;
            if ($fromCompleteEmail !== false) {
                $from = $fromCompleteEmail;
            }

            if ($fromName == 'WebName') {
                $fromName = $this->db->webName;
            }

            $headers = $this->getMailHeader($from, $fromName, $to);
        }

        if ($this->db->isCheckBounceWebMails) {
            $mail_send = $this->send_phpmailer_mail($to, $subject, $message, $headers, "-f" . $this->db->bounceWebEmail);
        } else {
            $mail_send = $this->send_phpmailer_mail($to, $subject, $message, $headers);
        }

        if ($mail_send) {
            if (isset($_SESSION['last_email_timestamp'])) {
                if (($_SESSION['last_email_timestamp'] + 60) <= time()) {
                    $_SESSION['last_email_timestamp'] = time();
                }
            } else {
                $_SESSION['last_email_timestamp'] = time();
            }
        }

        return $mail_send;
    }

    /**
     * @param $to
     * @param $subject
     * @param $message
     * @param string $headers
     * @param string $additional_params
     * @param string $fromName
     * @return bool
     */
    public function send_phpmailer_mail($to, $subject, $message, $headers = '', $additional_params = '', $fromName = '')
    {
        require_once(__DIR__ . '/PHPMailer-master/src/PHPMailer.php');
        require_once(__DIR__ . '/PHPMailer-master/src/Exception.php');
        require_once(__DIR__ . '/PHPMailer-master/src/SMTP.php');

        $mail = new PHPMailer();
        $mail->IsSMTP();
        $mail->Host = "smtp.imedia.com.pk";
        $mail->SMTPDebug = 0;
        $mail->SMTPAuth = true;
        $mail->SMTPSecure = "ssl";
        $mail->CharSet = 'utf-8';
        $mail->Port = 465;
        $mail->Username = "web@imdemo.xyz";
        $mail->Password = "y&e.>WT\%g41";
        $mail->From = "web@imdemo.xyz";
        $mail->Sender = "web@imdemo.xyz";
        $mail->SetFrom("web@imdemo.xyz", $this->ibms_setting('Site Name'));
        $mail->AddAddress($to);
        $mail->Subject = $subject;
        $mail->MsgHTML($message);

        if (!$mail->Send()) {
            $result = false;
        } else {
            $result = true;
        }

        return $result;
    }

    public function sendEmail($to, $subject, $message, $from, $fromName)
    {
        require_once __DIR__ . '/PHPMailer-master/src/PHPMailer.php';
        require_once __DIR__ . '/PHPMailer-master/src/Exception.php';
        require_once __DIR__ . '/PHPMailer-master/src/SMTP.php';

        $mail = new PHPMailer(true);

        $mail->SMTPDebug = 0;
        $mail->isSMTP();
        $mail->Host = "smtp.imedia.com.pk";
        $mail->SMTPAuth = true;
        $mail->Username = "web@imdemo.xyz";
        $mail->Password = "y&e.>WT\%g41";
        $mail->SMTPSecure = "ssl";
        $mail->Port = 465;
        $mail->setFrom('web@imdemo.xyz', $this->ibms_setting('Site Name'));
        $mail->addReplyTo($from, $fromName);
        $mail->addAddress($to);
        $mail->isHTML(true);
        $mail->Subject = $subject;
        $mail->Body = $message;

        if (!$mail->send()) {
            $result = false;
        } else {
            $result = true;
        }

        return $result;
    }


    /**
     * @param $image
     * @param string $width
     * @param string $height
     * @param bool $echo
     * @param false $pngBgColor
     * @param bool $imageWithWebUrl
     * @param bool $cache
     * @return bool|string
     */
    public function resizeImage($image, $width = 'auto', $height = 'auto', $echo = true, $pngBgColor = false, $imageWithWebUrl = true, $cache = true)
    {
        if (!$this->isImageExists($image) && $imageWithWebUrl) {
            return false;
        }

        $image1 = "/images/" . $image;

        $sqli = "SELECT img_cache FROM product_cache_image WHERE image = ? AND weight = ? AND height = ? ";

        $arrayi = [$image1, $width, $height];
        $data = $this->dbF->getRow($sqli, $arrayi);
        if (!$this->dbF->rowCount > 0) {


            $resize = WEB_URL . "/src/image.php?resize=true";
            if ($width != 'auto' || $width != '') {
                $resize .= "&width=" . $width;
            }
            if ($height != 'auto' || $height != '') {
                $resize .= "&height=" . $height;
            }

            if ($cache === false) {
                $resize .= "&nocache=nocache";
            }
            if ($pngBgColor !== false) {
                $resize .= "&color=" . $pngBgColor;
            }

            if ($imageWithWebUrl) {
                $image = WEB_URL . '/images/' . $image;
            }

            $path = "$resize&image=" . $image;
        } else {
            $path = WEB_URL . "/src/imagecache/" . $data['img_cache'];
        }
        if ($echo) {
            echo $path;
        } else {
            return $path;
        }
    }

    public function currentUrl($removeWebUrl = true, $addParameterSeprator = false)
    {
        $url = $this->db->defaultHttp . $_SERVER['HTTP_HOST'] . urldecode($_SERVER['REQUEST_URI']);
        if ($removeWebUrl) {
            $url = str_replace(WEB_URL, "", $url);
        }
        if (isset($_GET) && $addParameterSeprator) {
            $url .= "&";
        } elseif ($addParameterSeprator) {
            $url .= "?";
        }
        return $url;
    }


    public function isAdminLink()
    {
        $pageLink = $this->currentUrl();
        if (preg_match("@/" . ADMIN_FOLDER . "/@i", $pageLink)) {
            return true;
        }
        return false;
    }

    public function webUserName($user_id, $returnAll = true)
    {
        $sql = "SELECT * FROM accounts_user WHERE acc_id = '$user_id'";
        $userData = $this->dbF->getRow($sql);

        if ($returnAll === true) {
            return $userData;
        }
        return $userData[$returnAll];
    }


    public function setlog($title = "untitled", $ref_name = false, $ref_id = "", $desc = "", $transaction = true)
    {
        $user_email = $_SESSION["webUser"]["email"];

        $ipaddress = '';
        if (getenv('HTTP_CLIENT_IP'))
            $ipaddress = getenv('HTTP_CLIENT_IP');
        else if (getenv('HTTP_X_FORWARDED_FOR'))
            $ipaddress = getenv('HTTP_X_FORWARDED_FOR');
        else if (getenv('HTTP_X_FORWARDED'))
            $ipaddress = getenv('HTTP_X_FORWARDED');
        else if (getenv('HTTP_FORWARDED_FOR'))
            $ipaddress = getenv('HTTP_FORWARDED_FOR');
        else if (getenv('HTTP_FORWARDED'))
            $ipaddress = getenv('HTTP_FORWARDED');
        else if (getenv('REMOTE_ADDR'))
            $ipaddress = getenv('REMOTE_ADDR');
        else
            $ipaddress = 'UNKNOWN';



        $browser = "";
        foreach ($this->getBrowser() as $key => $val) {
            $browser .= "$key : $val <br />";
        }

        $sql = "INSERT INTO `activity_log` (`log_title`, `ref_name`, `ref_id`, `ref_user`, `log_desc`, `log_ip`, `log_browser`) VALUES (?,?,?,?,?,?,?) ";

        $arr = array($title, $ref_name, $ref_id, $user_email, $desc, $ipaddress, $browser);
        $this->dbF->setRow($sql, $arr, $transaction);
        return true;
    }

    private function getBrowser()
    {
        $u_agent = $_SERVER['HTTP_USER_AGENT'];
        $bname = 'Unknown';
        $platform = 'Unknown';
        $version = "";

        //First get the platform?
        if (preg_match('/linux/i', $u_agent)) {
            $platform = 'linux';
        } elseif (preg_match('/macintosh|mac os x/i', $u_agent)) {
            $platform = 'mac';
        } elseif (preg_match('/windows|win32/i', $u_agent)) {
            $platform = 'windows';
        }
        $ub = "";
        // Next get the name of the useragent yes seperately and for good reason
        if (preg_match('/MSIE/i', $u_agent) && !preg_match('/Opera/i', $u_agent)) {
            $bname = 'Internet Explorer';
            $ub = "MSIE";
        } elseif (preg_match('/Firefox/i', $u_agent)) {
            $bname = 'Mozilla Firefox';
            $ub = "Firefox";
        } elseif (preg_match('/Chrome/i', $u_agent)) {
            $bname = 'Google Chrome';
            $ub = "Chrome";
        } elseif (preg_match('/Safari/i', $u_agent)) {
            $bname = 'Apple Safari';
            $ub = "Safari";
        } elseif (preg_match('/Opera/i', $u_agent)) {
            $bname = 'Opera';
            $ub = "Opera";
        } elseif (preg_match('/Netscape/i', $u_agent)) {
            $bname = 'Netscape';
            $ub = "Netscape";
        }

        // finally get the correct version number
        $known = array('Version', $ub, 'other');
        $pattern = '#(?<browser>' . join('|', $known) .
            ')[/ ]+(?<version>[0-9.|a-zA-Z.]*)#';
        if (!preg_match_all($pattern, $u_agent, $matches)) {
            // we have no matching number just continue
        }

        // see how many we have
        $i = count($matches['browser']);
        if ($i != 1) {
            //we will have two since we are not using 'other' argument yet
            //see if version is before or after the name
            if (strripos($u_agent, "Version") < strripos($u_agent, $ub)) {
                $version = $matches['version'][0];
            } else {
                $version = $matches['version'][1];
            }
        } else {
            $version = $matches['version'][0];
        }

        // check if we have a number
        if ($version == null || $version == "") {
            $version = "?";
        }

        return array(
            'userAgent' => $u_agent,
            'name' => $bname,
            'version' => $version,
            'platform' => $platform,
            'pattern' => $pattern
        );
    }
} // trait end
